C# - Creating multiple lists based on int in Console - c#

I want to create multiple lists from a given size. Imagining it could look something like this :
int Size = int.Parse(Console.ReadLine());
for (int i = 0; i < Size; i++)
{
List<string> ListName + i = new List<string>();
}
So for example if size = 5 I'd get 5 lists :
ListName0
ListName1
ListName2
ListName3
ListName4

Create a container for the lists outside your loop:
int Size = int.Parse(Console.ReadLine());
List<List<string>> listContainer = new List<List<string>>();
for (int i = 0; i < Size; i++)
{
listContainer.Add(new List<string>());
}
You can access them via the index of the container object. For example listContainer[0] would be the first list<string> in the container.
Here is an example of accessing one of the lists and then accessing a value from said list:
int Size = int.Parse(Console.ReadLine());
List<List<string>> listContainer = new List<List<string>>();
for (int i = 0; i < Size; i++)
{
listContainer.Add(new List<string>());
}
listContainer[0].Add("Hi");
Console.WriteLine(listContainer[0][0]);

the common way is to use a dictionary
var list = new Dictionary<string, List<string>>();
int size = int.Parse(Console.ReadLine());
for (int i = 0; i < size; i++)
list["Name"+i.ToString()] = new List<string>();
how to use
list["Name1"].Add( "hello world");

Related

Resizing and initializing 2D array C#

I have a 2D array of type string which I want to modify and resize inside some loop. My main goal is to use minimum memory by creating a 2d array which will be modified every iteration of loop and the add a char to an appropriate cell in this array. Here is my code:
static void Main(string[] args)
{
int maxBound = 100;//length of freq array
Random rnd1 = new Random();
int numLoops = rnd1.Next(1000, 1200);//number of total elements in freq array
int[] freq = new int[maxBound];//freq array
string[,] _2dim = new string[maxBound, numLoops];//rows,columns
Random rnd2 = new Random();
for (int i = 0; i < numLoops; i++)
{
int s = rnd2.Next(maxBound);
freq[s]++;
//Here I try to add `*` to the _2dim array while resizing it to the appropriate size
}
}
What is the main approach for the solution ? Thanks
Instead of a 2D array you might want to use a jagged one. Briefly, a 2D array is always an N x M matrix, which you cannot resize, whereas a jagged array is an array of arrays, where you can separately initialize every inner element by a different size (see the differences in details here)
int maxBound = 100;
Random rnd = new Random();
int numLoops = rnd.Next(1000, 1200);
string[][] jagged = new string[numLoops][];
for (int i = 0; i < numLoops; i++)
{
int currLen = rnd.Next(maxBound);
jagged[i] = new string[currLen];
for (int j = 0; j < currLen; j++)
jagged[i][j] = "*"; // do some initialization
}
You should use a list of type string nested in a List. Then you can modify this lists. For iterating through this you should use two for loops.
List<List<string>> l = new List<List<string>> { new List<string> { "a", "b" }, new List<string> { "1", "2" } };
Iteration example:
for(int i = 0; i < l.Count; i++)
{
for(int j = 0; j < l[i].Count; j++)
{
Console.WriteLine(l[i][j]);
}
}

(jagged array) Array of an Array: automatically create in while loop, how to initialize?

I would like to create an array of an array from a text file...
There are 20000 line with 21 strings in each line separated by ',' .
I would like to read each line and make it into an array , each line being a new array within.
So I wanted to create the jagged array by starting it like this:
string[][] SqlArray = new string[200000][21];
But it gives: ERROR MESSAGE : Invalid rank specifier: expected ',' or ]
How would I create this array or initialize it?
I will be populating the data in the array like this:
while (true)
{
string theline = readIn.ReadLine();
if (theline == null) break;
string[] workingArray = theline.Split(',');
for (int i = 0; i < workingArray.Length; i++)
{
for (int k = 0; k < 20; k++)
{
SqlArray[i][k] = workingArray[k];
}
}
}
Thank you
That type of initialization only works in Java. You must declare an array of arrays then initialize each in a loop.
string[][] SqlArray = new string[21][];
for(int index = 0; index < SqlArray.Length; index++)
{
SqlArray[index] = new string[2000000];
}
Alternatively, you can use a non-jagged array. It will probably work for what you need.
string[,] SqlArray = new string[21 , 2000000];
It can be accessed like so:
SqlArray[2,6264] = x;
To anyone who is interested this is how I ended up implementing it:
TextReader readIn = File.OpenText("..\\..\\datafile.txt");
string[][] SqlArray = new string[rowNumCreate][];
int e = 0;
while (true)
{
string theline = readIn.ReadLine();
if (theline == null) break;
string[] workingArray = theline.Split(',');
SqlArray[e] = new string[valuesInRow +1];
for (int k = 0; k < workingArray.Length; k++)
{
SqlArray[e][k] = workingArray[k];
}
e++;
}
The file being read is a simple mock database set as a flat file that was auto-generated to test an algorithm that I am implementing, which works with jagged arrays; hence instead of working with a data base I just created this for ease of use and to increase and decrease size at will.
Here is the code to build the text file:
Random skill_id;
skill_id = new Random();
// int counter =0;
string seedvalue = TicksToString();
int rowNumCreate = 200000;
int valuesInRow = 20;
string lineInFile = seedvalue;
string delimiter = ",";
for (int i = 0; i < rowNumCreate; i++)
{
for (int t = 0; t < valuesInRow; t++)
{
int skill = skill_id.Next(40);
string SCon = Convert.ToString(skill);
lineInFile += delimiter + SCon;
}
if (rowNumCreate >= i + 1)
{
dataFile.WriteLine(lineInFile);
lineInFile = "";
string userPK = TicksToString();
lineInFile += userPK;
}
}
dataFile.Close();
public static string TicksToString()
{
long ms = DateTime.Now.Second;
long ms2 = DateTime.Now.Millisecond;
Random seeds;
seeds = new Random();
int ran = seeds.GetHashCode();
return string.Format("{0:X}{1:X}{2:X}", ms, ms2, ran).ToLower();
}
I am still a student so not sure if the code is A-grade but it works :)

Frequency for duplicate items in a list C#

I'm on VS Windows Forms Application and I'm NOT using any other form of coding (e.g. linq) - just the basic style of coding which goes like this;
List<string> brandList = new List<string>();
//brand items are added to the list
//go through list
for(int i = 0; brandList.Count; i++)
{
if(brandList[i]== "BrandName1")
{
//count for that brandName
}
}
What I want to know is how to I get the count for how many times a brand has occurred in the list?
This code will not need to be case sensitive either because it is being read in from a file..
If you don't want/can't use LINQ you could use a Dictionary<string, int>:
Dictionary<string, int> dict = new Dictionary<string, int>();
for(int i = 0; brandList.Count; i++)
{
string brand = brandList[i];
int count = 1;
if(dict.ContainsKey(brand))
count = dict[brand] + 1;
dict[brand] = count;
}
Now you have all brands as key and their counts as value.
I really don't see the problem because your code is already have the solution if I understand correctly the question. You go through the elements, if the current element is the element to count you increment a variable.
const string BRAND = "BrandName1";
int count = 0;
foreach (string brand in brandList)
{
if (string.Compare(brand, BRAND, true))
{
count++;
}
}
Obviously you can use for (int i = 0; i < brandList.Count; i++) and brandList[i] instead of foreach, but it's more like C#.
How about this:
List<string> brandList = new List<string>();
//brand items are added to the list
//sort list to get number of occurences of each entry
brandList.Sort();
var occurences = new List<KeyValuePair<string, int>>();
//go through list
var numBrand = 1;
for (int i = 0; i < brandList.Count-1; i++)
{
if (string.Equals(brandList[i + 1], brandList[i]))
{
numBrand++;
}
else
{
occurences.Add(new KeyValuePair<string, int>(brandList[i], numBrand));
numBrand = 1;
}
}
var highestCount = occurences.OrderBy(o => o.Value).ToList()[0].Key;
It might skip the last entry if that is a single occurences but then that's not the highest anyway.
Would that do the trick for you?

Do you always have to start at the index zero when writing a 2D list?

I want to fill in a 2Dlist, but start at the third position [2]. Is this somehow possible?
A short code for understanding what i mean:
List<List<string>> List2D = new List<List<string>>();
for (int i = 0; i < 5; i++)
{
List2D[2].Add("i")
}
I get the following error:
Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index
EDIT: Any idea how to fill in a 4D list?
List<List<List<List<string>>>> List4D = new List<List<List<List<string>>>>();
for (int i = 0; i < List1.Count; i++)
{
List<List<List<string>>> List3D = new List<List<List<string>>>();
for (int j = 0; j < List2.Count; j++)
{
List<List<string>> List2D = new List<List<string>>();
for (int k = 0; k < List3.Count; k++)
{
List<string> Lijst1D = new List<string>();
List2D.Add(Lijst1D);
}
List3D.Add(List2D);
}
List4D.Add(List3D);
}
So later I can call: List4D[2][3][0].Add("test");
Since you just created your List2D and not added any nested list into it, you can't access its third element (there is nothing there).
You have to add some items first:
List<List<string>> List2D = new List<List<string>>();
List2D.Add(new List<string>());
List2D.Add(new List<string>());
List2D.Add(new List<string>());
for (int i=0; i<5; i++)
{
List2D[2].Add("i")
}
Update
Well, core idea of filling that list remains the same: if you want to access List4D[2][3][0] - first you need to fill all of lists in "path".
You can do it something like this:
List<List<List<List<string>>>> List4D = new List<List<List<List<string>>>>();
int i1 = 2, i2 = 3, i3 = 0;
for (int i = 0; i <= Math.Max(i1, 1); i++)
List4D.Add(new List<List<List<string>>>());
for (int i = 0; i <= Math.Max(i2, 1); i++)
List4D[i1].Add(new List<List<string>>());
for (int i = 0; i <= Math.Max(i3, 1); i++)
List4D[i1][i2].Add(new List<string>());
List4D[i1][i2][i3].Add("test");
Frankly, idea of 4D list looks a little bit "syntetic". In real application probably it is not the best data structure because of clumsy addressing.

storage selected listbox items into a new array

How can I store the selected item(s) in a listbox to a new array? Like we select the items and then do the button's action, e.g.
string[] domains = new string[listBox1.Items.Count];
for (int i = 0; i < listBox1.Items.Count; i++)
{
domains[i] = listBox1.SelectedIndices[i].ToString();
}
Your code won't work because index i is not used to indicate SelectedIndices, but Items.
So update it:
string[] domains = new string[listBox1.SelectedIndices.Count];
for (int i = 0; i < listBox1.SelectedIndices.Count; i++)
{
domains[i] = listBox.Items[listBox1.SelectedIndices[i]].ToString();
}
What I prefer:
List<string> domains = new List<string>();
for (int i = 0; i < listBox1.SelectedIndices.Count; i++)
{
domains.Add(listBox.Items[listBox1.SelectedIndices[i]].ToString());
}
What about this:
string[] domains = listBox1.SelectedItems.OfType<string>().ToArray();

Categories