Incrementing concatenated list name - c#

Say for example I have a number (which will change each run time) assigned to the following variable:
var number = 3;
I would like to create this many lists, whose names have a number at the end which increments every time, as follows:
list_0
list_1
list_2
I am declaring a list in the following standard format:
List<double> list = new List<double>();
I assume you would use a loop, but I am unsure as to how to correctly assign the name dynamically. Here's what I have:
for (var i = 0; i < number; i++)
{
List<double> ("list_" + i) = new List<double>();
}
Any help would be appreciated

This isn't possible the way you intend to, although you might have some luck using the Reflection API.
This is an anti-pattern though: you should know before compile time what your lists are intending to do and give them a name that describes their purpose. If you don't, you might want to not name them and simply keep their references in a list, like this:
List<List<Double> myLists = new List<List<double>>();
var listX = new List<double>(new[]{5.0, 2.5, 3.2});
myLists.add(listX);
Which will make it a lot easier for you to work with them.

What you're trying to do is a bad practice. Most of the code written nowadays is already hard enough to read, if you try to add variables into variables names (and I'm happy the compiler forbids this) it would be truly infernal.
Instead, think of a data structure that would fit your needs; you need to have multiple variables, ordered from 0 to X. Sounds like a list to me, so you can create a List of List instead.
So if you have int number = 3; you can do
List<List<double>> lists = new List<List<double>>();
for (int i = 0; i < number; i++)
{
lists[i] = new List<double>();
}
If you want to access one of your lists after that, you easily can use the index or the LINQ .ElementAt()
List<double> listNumberTwo = lists[2];
List<double> listNumberTwo = lists.ElementAt(2);

Related

Index Out of Range on accessing List<List<T>> with For loops

Hobbyist start C# coder here. Think I am missing something basic here. I am trying to create a new List by parsing through a List> using two for loops. I am getting Index Out of Range although from what I can tell in debugging, there is data in the Deal object in the [index][index] location being accessed.
List<List<Deal>> Deals = await Database.LoadRecordsAsync(form, depts);
for (int dept = 0; dept <= Deals.Count; dept++)
{
List<Deal> batch = new List<Deal>();
for (int deal = Deals[dept].Count; deal >= 0; deal--)
{
batch.Add(Deals[dept][deal]); // Error here
}
}
Deals in debugging has indexes as expected with data as expected. Am I initializing something incorrectly?
The problem is the following line:
deal = Deals[dept].Count
This line should change as below:
deal = Deals[dept].Count - 1
as well the upper bound of the first for. The following
dept <= Deals.Count
should change as below:
dept < Deals.Count
Generally speaking, if you declare an array of n items the last item of the array can be accessed by using the index n-1.
That being said if you declare deal as Deals[dept].Count and later on you attempt to read this:
Deals[dept][deal]
you are out of the range of the array you have defined.

c# - How to create 2D array with unknown number of rows, but known number of columns?

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();

Add one item multiple times to same List

What I am trying to achieve is to add one item to a List, multiple times without using a loop.
I am going to add 50 numbers to a List and want all of those number to be equal to, let's say, 42. I am aware that I can simply create a small loop that runs 50 times and adds the same item over and over again, as such;
List<int> listFullOfInts = new List<int>();
int addThis = 42;
for(int i = 0; i < 50; i++)
listFullOfInts.Add(addThis);
What I am trying to do is something on the lines of;
listFullOfInts.AddRange(addThis, 50);
Or something that is similar to this at least, maybe using Linq? I have a vague memory of seeing how to do this but am unable to find it. Any ideas?
You can use Repeat:
List<int> listFullOfInts = Enumerable.Repeat(42, 50).ToList();
Demo
If you already have a list and you don't want to create a new one with ToList:
listFullOfInts.AddRange(Enumerable.Repeat(42, 50));
If you want to do add reference types without repeating the same reference, you can use Enumerable.Range+Select:
List<SomeClass> itemList = Enumerable.Range(0, 50)
.Select(i => new SomeClass())
.ToList();
You can't do it directly with LINQ since LINQ is side effect free but you can use some of what's found in the System.linq namespace to build the required.
public static void AddRepeated<T>(this List<T> self,T item, int count){
var temp = Enumerable.Repeat(item,count);
self.AddRange(temp);
}
you can then use that as you propose in your post
listFullOfInts.AddRepeated(addThis, 50);

Which collection type to use?

I have a scenario where I have a list of classes, and I want to mix up the order. For example:
private List<Question> myQuestions = new List<Question>();
So, given that this is now populated with a set of data, I want to mix up the order. My first thought was to create a collection of integers numbered from 1 to myQuestions.Count, assign one at random to each question and then loop through them in order; however, I can’t seem to find a suitable collection type to use for this. An example of what I mean would be something like this:
for (int i = 0; i <= myQuestions.Count -1; i++)
tempCollection[i] = myQuestions[rnd.Next(myQuestions.Count-1)];
But I’m not sure what tempCollection should be – it just needs to be a single value that I can remove as I use it. Does anyone have any suggestions as to which type to use, or of a better way to do this?
I suggest you copy the results into a new List<Question> and then shuffle that list.
However, I would use a Fisher-Yates shuffle rather than the one you've given here. There are plenty of C# examples of that on this site.
For example, you might do:
// Don't create a new instance of Random each time. That's a detail
// for another question though.
Random rng = GetAppropriateRandomInstanceForThread();
List<Question> shuffled = new List<Question>(myQuestions);
for (int i = shuffled.Count - 1; i > 0; i--)
{
// Swap element "i" with a random earlier element it (or itself)
int swapIndex = rng.Next(i + 1);
Question tmp = shuffled[i];
shuffled[i] = shuffled[swapIndex];
shuffled[swapIndex] = tmp;
}
You could use Linq and order by a random value:
List<string> items = new List<string>();
items.Add("Foo");
items.Add("Bar");
items.Add("Baz");
foreach (string item in items.OrderBy(c => Guid.NewGuid()))
{
Console.WriteLine(item);
}
temp Collection should be same type as myQuestions.
I would also suggest a change in your code:
for (int i = 0; i <= myQuestions.Count -1; i++)
to
for (int i = 0; i < myQuestions.Count; i++)
Does the same thing, but this is how most programers do it so it will make your code simpler to read.

Define a double array without a fixed size?

Hello i have a problem with c# Arrays. I need a array to store some data in there...
My Code is that
double[] ATmittelMin;
ATmittelMin[zaehlMittel] = Gradient(x, xATmax, y, yATmax);
But the compiler says: not defined var
How can i define a double array without a fixed size ?
Thanks a lot!
Arrays are always fixed in size, and have to be defined like so:
double[] items1 = new double[10];
// This means array is double[3] and cannot be changed without redefining it.
double[] items2 = {1.23, 4.56, 7.89};
The List<T> class uses an array in the background and redefines it when it runs out of space:
List<double> items = new List<double>();
items.Add(1.23);
items.Add(4.56);
items.Add(7.89);
// This will give you a double[3] array with the items of the list.
double[] itemsArray = items.ToArray();
You can iterate through a List<T> just as you would an array:
foreach (double item in items)
{
Console.WriteLine(item);
}
// Note that the property is 'Count' rather than 'Length'
for (int i = 0; i < items.Count; i++)
{
Console.WriteLine(items[i]);
}
From what I see you did not declare the zaehlMittel variable. I guess this is what the compiler complains about.
Apart from that, even though you can of course determine the value of that variable programmatically, the moment you want to create an array its size must be known. This is the way arrays work.
In case you cannot do that easily, I suggest using some sort of dynamic datastructure, like a list or a set. Then, once all elements have been added, you are of course still free to create an array from that, as by that time you know the number of elements (even though there are convenience methods like toArray() that will even take care of that).
You have to instanciate the array before using it:
double[] ATmittelMin = new double[10];
ATmittelMin[zaehlMittel] = Gradient(x, xATmax, y, yATmax);
The obvious solution that springs to mind is to use a List:
List<double> ATmittelMin = new List<double>();
ATmittelMin.Add(Gradient(x, xATMax, y, yATMax);
But if you don't want to convert from a list to an array you can grow the array later:
double[] ATmittelMin = new double[10];
// Some code
int index = some_value;
if (index >= TmittelMin.Length)
{
Array.Resize(ATmittelMin, index+5); // So we're not constantly resizing the array
}
It's not ideal as you're doing a lot of the work that List is doing behind the scenes - probably a lot more efficiently than you can.

Categories

Resources