So I have an array with 4 columns. And I also have a separate list which defines each column with a string. Something like the snippet below:-
List<string> headers = new List<string>();
headers.Add("Name");
headers.Add("Number");
headers.Add("ID");
headers.Add("License");
The array looks like this
Max 32445 1 KPFG35
Bill 33234 2 DGWEF9
Ruth 89428 3 SFD3FG
... and so on.
Now, lets say someone wants that same array however with the columns arranged as ID, Name, Number, License. How can I manipulate the columns in the array and produce a new one to return? thank you for any help!
so in the case mentioned above, it would return
1 Max 32445 KPFG35
2 Bill 33234 DGWEF9
3 Ruth 89428 SFD3FG
I don't know if you have to use List or not. But here is a solution that may help you. I suggest you to use DataTable.
Basically I have create a form with datagridview and a button,
DataTable dt = new DataTable();
In form's load,
private void Form1_Load(object sender, EventArgs e)
{
dt.Columns.Add("Name");
dt.Columns.Add("Number");
dt.Columns.Add("ID");
dt.Columns.Add("License");
string[] array = { "Max", "32445", "1", "KPFG35", "Bill", "33234", "2", "DGWEF9", "Ruth", "89428", "3", "SFD3FG" };
for (int i = 0; i < array.Length + 1; i++)
{
if (i != 0 && i % 4 == 0) // every 4th item should be split from list
{
string[] tempArray = new string[4]; //temp array will keep every item until 4th one.
tempArray = array.Take(i).ToArray(); //Take until 4th item.
array = array.Skip(i).ToArray(); //then we don't need that items so we can skip them
dt.Rows.Add(tempArray); //Row is done.
i = -1; //Every skip will generate a new array so it should go back to 0.
}
}
dataGridView1.DataSource = dt;
}
And there is a button to change order with SetOrdinal,
private void button1_Click(object sender, EventArgs e)
{
dt.Columns["ID"].SetOrdinal(0);
dataGridView1.DataSource = null;
dataGridView1.DataSource = dt;
dataGridView1.Refresh();
}
Output,
After button click ID column was at 0. (the second one)
Hope helps, (Not sure if you have to use List<string>, but it might be a clue for you.
You are not actually shifting the columns but are rearranging them. Shifting means the columns remain in the same order but the row is rotated left or right. Anyway, doing it without using data structures but just using arrays would take the following form in code:
//Assuming the array is of type string
string[,] arr <--- the array we are talking about
string[,] ta = new string[3,4]; //a temporary array
/* The columns are arranged in the order: Name Number ID License
and we want it as: ------------ ID Name Number License
So, if the order of the columns is: 1 2 3 4,
we now want it as: -------------- 3 1 2 4 */
string order = "3124";
for(int i=0; i<3; i++){
for(int j=0; j<4; j++){
int k = int.Parse(order[j].ToString())-1;
//k stores the column number in arr to be added to ta
ta[i,j] = arr[i,k];
}
}
//ta now stores arr in the new order
//you can either change the value of arr to the new array: arr = ta;
//or you can now make all your references to the new array ta
Hope it helps you.
As others have suggested: It would probably be better for you to store these as objects for maintainability.
But It sounds like you have a requirement that the array is what you want to keep. Since all you really want to do is move a column over you and produce a new list you could do something like:
private static IEnumerable<string> MoveIndexToFirst(List<string> input)
{
for(int i = 0; i < input.Count; i+=4 )
{
yield return input[i+2];
yield return input[i];
yield return input[i+1];
yield return input[i+3];
}
}
usage:
List<string> newList = MoveIndexToFirst(yourData).ToList();
Related
i am getting string array on runtime like this
string[] array1 = {"5", "4", "2"};
values in array is added on runtime on the basis of checkbox selection from
screen (Note: i have 7 check boxes on screen )
if i check 3 check boxes then 3 values will be add in array1 but i want to add
zero at the end of the array in remaining 4 positions in array like this :
string[] array1 = {"5", "4", "2","0" ,"0","0" , "0"};
during runtime just to fix all 7 position in array ...what should i do ??
I don't get the usage of your requirement. But you can fill up the array with "0" with the following code:
List<string> list = array1.ToList();
for (int i = array1.Length; i < 7; i++)
{
list.Add("0");
}
array1 = list.ToArray();
You can do the following:
const int paddedSize = 7;
var newArray = array1.Concat(Enumerable.Repeat("0", paddedSize - array1.Length)).ToArray();
But maybe you'll understand it better without using Linq; the type you want to use is List<string> which can be dynamically resized, arrays can't. In order to get a list out of an array, you can use the linq extension:
var resized = array1.ToList();
Or
var resized = new List<string>(array1);
And now you simply add 0s until the total count of items is 7:
while (resized.Count < paddedSize)
resized.Add("0");
And back to an array:
var newArray = resized.ToArray();
I have two lists, one list have some record (not known specific no of rec, but not more than 13 records) and second list have only empty value. I am using if condition on these two list. And want to add these two list in one array. I am using this code:
for (int i=0; i>12; i++)
{
List<string> excList = new List<string>();
//added column from table, which can varies
excList.Add((string)column.ColumnName);
string[] excelList = new string[] { };
List<string> stack = Enumerable.Range(excList.Count, 13)
.Select(z => string.Empty)
.ToList<string>();
if (excList.Count > i)
{
excelList = excList.ToArray();
}
if (excList.Count <= i)
{
excelList = stack.ToArray();
}
eCol0 = excelList[0].ToString();
//show first value, after adding two list in excelList
response.Write(eCol0);
}
Using this code, when the second condition started and list (excList) is adding in array (excelList) then excelList is showing only second list data.
I want to insert these two list (excList and stack) into arrayList (which have range of 13).But these two list must add on the bases of if condition as I'm using if condition in above code.
Well you never Add something to your string array excelList. You always assign it new.
Using an array is also not the best for adding values, since you need to know beforehand the size of the array.
If you really want an array in the end with both results, you should do something like this:
List<string> excList = new List<string>();
... fill your excList here and initialize the stack list with whatever you need ...
excList.AddRange(stack);
string[] excelList = excList.ToArray();
Edit: as the comments mention, your question is a little bit confusing and you are using one big loop with no clear reason why and adding empty values makes no sence too... so i tried to get the essence out of what you wanted to know
Edit:2
Wait a second, I think you want in the end, an array of strings, with the size of 13, where the elements are at least string.empty
List<string> excList = new List<string>();
//added column from table, which can varies
excList.Add((string)column.ColumnName);
string[] excelList = new string[13];
for (int i = 0; i < excList.Count; i++)
{
excelList[i] = excList[i];
}
for (int i = excList.Count; i < 13; i++)
{
excelList[i] = string.Empty;
}
no outer loop necessary
You've written a huge amount of confusing code that could be considerably more compact.
Through th commnts I was able to understand that you have a list of N strings, where N could be between 1 and 13, and you want to turn it into an array of 13 strings with all your list items at the start, and empty strings at the end
So a list of:
"a", "b", "c"
Becomes an array of:
"a", "b", "c", "", "", "", "", "", "", "", "", "", ""
If you want a one liner to generate you a list of 13 strings, from a List x of up to 13 strings:
string[] arrayOf13 = x.AddRange(Enumerable.Repeat("", 13 - x.Count)).ToArray();
If your list x will have an unknown number more than 13:
string[] arrayOf13 = x.AddRange(Enumerable.Repeat("", 13)).Take(13).ToArray();
Or without LINQ using either a for or a while loop:
for(; x.Count < 13; x.Add(""))
string[] arrayOf13 = x.ToArray();
while(x.Count < 13)
x.Add(""));
string[] arrayOf13 = x.ToArray();
If you're willing to have the strings be null rather than empty, you can just declare an array of size 13 (all null) and then use Array.CopyTo():
string[] arrayOf13 = new string[13];
x.ToArray().CopyTo(arrayOf13, 0);
It seems your goal is to get an array of 13 strings (excelList), where each element is eigher string.Empty by default or the corresponding (same index) element from some source list (excList).
So a short-code solution would be to first create a 13-element array, initialized with 'string.Empty' and then copy the source lists elements over, limited to max 13 elements:
var excelList = Enumerable.Repeat(string.Empty, 13).ToArray();
excList.CopyTo(0, excelList, 0, Math.Min(13, excList.Count));
I've a line in the bottom part of the main screen of the game, that every time the scene is loaded, it shows a different tip (how to play, how to change music...).
The question is that I'm using Random.Range for that but, honestly, I'll prefer a way where all tips are showed, one by one in a random way, but without repeating any of them.
My code is as follows:
int randNum;
void Start () {
randNum = Random.Range(0,5);
}
void Update () {
switch (randNum)
{
case 0:
// blah, blah, blah...
case 1...
How can I achieve what I want?
Thans for yout timeeee :)
You can remove the switch statement and store each message in a list.
var tips = new List<string>();
tips.Add("The clouds are white");
...
Then you can randomize the elements in the list (more on that here) and show tips one by one. All you need is to keep track of the index. Example:
// This needs to be a field.
int index = 0;
void ShowTip()
{
// TODO: make sure index is not equal or greater than tips.Count
tip = tips[index];
index++;
// Display the tip
}
What you can do is to shuffle your list of tip. The Fisher-Yates shuffle is one of the most common.
static Random _random = new Random();
static void Shuffle<T>(T[] array)
{
int n = array.Length;
for (int i = 0; i < n; i++)
{
// Use Next on random instance with an argument.
// ... The argument is an exclusive bound.
// So we will not go past the end of the array.
int r = i + _random.Next(n - i);
T t = array[r];
array[r] = array[i];
array[i] = t;
}
}
public static void Main()
{
string[] array = { "tip 1", "tip 2", "tip 3" };
Shuffle(array);
foreach (string value in array)
{
Console.WriteLine(value);
}
}
output
net
dot
perls
source
Suppose your messages are stored in a list of string declared at the global level together with your random class and with an additional List of strings initially empty
List<string> needToDisplayMessages = new List<string>();
List<string> base_messages = new List<string>{"message1","message2","message3","message4","message5"};
Random rnd = new Random();
In your update method check if the list of messages to be displayed is empty and if yes copy the messages from the list with the predefined message. Now use the random instance to choose the index of the message to display and get it from the dynamic list. Finally remove the message from the list of message still to be displayed.
void Update () {
// We refill the list if it is empty
if(needToDisplayMessages.Count == 0)
needToDisplayMessages.AddRange(base_messages);
// Choose a random number topped by the count of messages still to be displayed
int index = rnd.Next(0, needToDisplayMessages.Count);
string message = needToDisplayMessages[index];
..... display the message someway .....
// Remove the message from the list
needToDisplayMessages.RemoveAt(index);
}
Of course, if you want to display the messages in sequential order there is no need of this but (as already explained) just an index. But if you want to randomly choose the message until you have shown all of them and then restart the cycle, perhaps this approach is not too much complex.
I am trying to create 2-dimensional array of ints with two columns, but an unknown amount of rows. I know that in order to create the 2D array itself I do the following:
List<List<int>> myList = new List<List<int>>();
But how do I modify this to specify the number of columns? And how would I add a row to this array?
You could use a List of int arrays. The List would represent the rows, and each int array in the List would be one row. The length of each array would equal the amount of columns.
List<int[]> rows = new List<int[]>();
int[] row = new int[2];
row[0] = 100;
row[1] = 200;
rows.Add(row);
As long as each int array is length two (int[] row = new int[2]), all rows will have two columns. The List can have any number of int arrays added to it in this way.
There is no way to create 2D array (or any other sort of array) with unknown number of elements. Once you initialize it you have to provide number of elements.
The syntax for multidimensional array is the following:
var arr = new int[k, l, n,...]
You can create so called jagged array, i.e. array of arrays and initialize it in the cycle. You will still need to initialize it with a number of subarrays and then fill with those subarrays of given lengths:
var arr = new int[][n];
for (int i = 0; i < arr.Length; i++)
{
arr[i] = new int[subArrayLength];
}
What you actually do is List of Lists which can have any number of "rows" of any length. You can add new list of specific length to an outer list by List method Add() and the same way you can add an element to any of inner List.
So basically to add a "row" you would need the following:
List<List<int>> table = new List<List<int>>();
table.Add(Enumerable.Repeat(defaultValue, numberOfColumns).ToList());
To add a column you would need something like this:
foreach (var row in table)
{
row.Add(defaultValue);
}
It seems that you want to simulate table structure - for that I would suggest to create a class to incapsulate table logic from above inside so that any addition of row will cause addition of outer List of current numberOfColumns size and addition of column will cause addition of an element to all outer lists.
However if you need a fixed number of columns the best alternative you can use is to declare a new class with your columns mapped to the properties of the class and then simply declare a List like it is described in the following answer as #shash678 pointed
Original answer: Consider using a List<Tuple<int, int>>.
Explanation: To begin with, an int[] is not a List<>. From the spirit of your question you seem to have the need to group several units of data together with a finite size, like a records in a table. You could decide to create a POCO with a more descriptive name (which would increase code readability and help with semantics), use an array of fixed size, or use a Tuple. Since there is no mention as to the need for mutability, and the size of the inner "array" will be fixed, I would suggest a Tuple. Through type safety you will ensure that the size and shape of each new object added to the list of Tuples is correct.
Your fist and second questions would be taken care, as far as the 3rd, see: Tuple Pair
e.g. list.Add(Tuple.Create<int,int>(1,1));
I feel like these answers are leading you down a bad path. When learning how to program, you should also consider best practices. In this case your code is what you should use. If you can avoid setting explicit array size, you should(In my opinion). List were create for this purpose. This sample app explains how to use the list correctly in this scenario. My personal opinion is to avoid using arrays if you can.
int someNumberOfRow = 10;//This is just for testing purposes.
Random random = new Random();//This is just for testing purposes.
List<List<int>> myList = new List<List<int>>();
//add two elements to the an arraylist<int> then add this arraylist to myList arraylist
for(int i = 0; i < someNumberOfRow; i++)
{
//Create inner list and add two ints to it.
List<int> innerList = new List<int>();
innerList.Add(random.Next());
innerList.Add(random.Next());
//Add the inner list to myList;
myList.Add(innerList);
}
//This prints myList
for(int i = 0; i < myList.Count; i++)
{
Console.WriteLine((i + 1) + ": " + myList[i][0] + " - " + myList[i][1]);
}
Console.WriteLine("\n\n");
//If the app may scale in the future, I suggest you use an approach similar to this
foreach(List<int> sublist in myList)
{
foreach(int columns in sublist)
{
Console.Write(columns + " ");
}
Console.WriteLine();
}
Console.ReadLine();
I have a 2D list which holds sentences and a score generated for that sentence, I need to get the sentence which has the highest score.
So the list is:
("This is sentence one", "302")
("And another sentence", "154")
("Oh and heres another", "528")
The function the list is formed and also where I need to get the sentence with the highest score is this:
protected void buildSummary()
{
scoreCoord2 = -1;
for (int x1 = 0; x1 < results.Length; x1++)
{
SortedList<int, string> paragraphScoreslist = new SortedList<int, string>();
for (int x2 = 0; x2 < results[x1].Length; x2++)
{
scoreCoord2++;
paragraphScoreslist.Add(intersectionSentenceScores[scoreCoord2], results[x1][x2]);
}
int maxValue = paragraphScoreslist.Max(k => k.Key);
//string maxValue = paragraphScoreslist.TryGetValue;
TextboxSummary.Text = maxValue.ToString();
}
}
I'm able to get the highest int value from the sorted list, but don't know how to get the string which is tied to it. I think I need to use TryGetValue but I don't know to use it in a 2D list which in of its self I haven't used before.
If you have control over the array replace it with a SortedList and you can use the SortedList.Max() function without hassle. A sorted list is probably the best take on, as it inherently sorted (which you want), so getting the highest (i.e. Max value) will be faster than an unsorted array, or an unsorted List.
If you don't have control over the data you are receiving, project the data you are getting into a new form (the above SortedList
Going with the example you put up in your post, lets call it "matrix" for simplicity sake:
string[,] matrix =
{
{ "This is sentence one", "302" },
{ "And another sentence", "154" },
{ "Oh and heres another", "528" }
};
Here is the code to put it into a sorted List:
// New instance, pretty simple
SortedList<int, string> list = new SortedList<int, string>();
// Loop through the array and project it into a new form
for(int i = 0; i <= matrix.Length(0); i++) {
list.Add(Convert.ToInt32(matrix[i, 1]), matrix[i, 0]);
}
// Get the max value in the list
var maxValue = list.Max(k => k.Key);
Now you can do what you want with the value. If you want to get the sentence for it you should use the TryGetValue method, but that's up to you. Like this:
string sentence= string.Empty;
if (list.TryGetValue(maxValue, out sentence))
{
// Do something with the string you got
}
For more information how to use the whole Try... methods you should read up on out and ref parameters.
Anything else?