I have a problem on creating a set of list in array
this is my coding but it's wrong one, any correction for this?
List<string>[] item = new List<string>[10]();
I want to create 10 list in string named as item but I can't do it
and then how can I store more than 1 element in each of the 10 item list??
item[1].add(a); //when I want to print that a I use item[1][0]
item[1].add(b); //when I want to print that b I use item[1][1]
item[2].add(aa);
item[2].add(bb);
but how can I store element in each of the list?
If you KNOW for certain that you want exactly ten lists, you can use an array instantiated to 10 items, each a list of string.
List<string> [] items = new List<string> [10];
Each List is not initialized, so you need to initialize your list before you can use it and each list can be accessed via normal indexer syntax..
if (items[0] == null)
items[0] = new List<string>();
Once initialized, you can fill in your data.
items[0].Add("another string");
If you wanted to pre-initialize each list so that you do not get a NullReferenceException, do so in a loop.
for (var i = 0; i < items.Length; i++)
items[i] = new List<string>();
However, if you think that your items may need to hold more List<string> down the road, just simply use a list of lists.
List<List<string>> items = new List<List<string>>();
List wraps array and gives you some nice syntactic sugar and optimizations for expanding arrays which makes your life a lot easier. You can still use indexer syntax to access each list within your list.
if (items[0] == null)
items[0] = new List<string>();
items[0].Add("another string").
As per your comments
"I want 10 separete list that have dynamic space"
You can define your collection as follows.
List<string> [] collection= new List<string> [10];
for(int i=0; i<10; i++)
collection[i] = new List<string>();
or, if you don't care size of the array then you can use this.
List<List<string>> collection = new List<List<string>>();
Related
I cannot find an answer because it seems too much specific. So here's my issue with C#.
We can add another list to another one as a clone like this
list2 = new List<int>(list1);
What I want to know is how can I add a List into another one without any reference of the child?
List<List<List<int>>> wireCoords = new List<List<List<int>>>();
List<int> coord = new List<int>();
for(int i = 0; i < inputSplits.Length; i++)
{
coord.Add(0);
coord.Add(0);
wireCoords[i].Add(coord);
}
AS soon the wireCoords[0][0] list change, it also change inside wireCoords[1][0]
How can I fix this?
Two things. You cannot access a List via [i] accessor unless it has content at that index. Second, you can copy the values of a list by using List1.AddRange(List2). After this, changing List2 will not change List1.
In your for loop, the number of items grow to inputSplits.Length * 2 for every index of wiredCoords. To explain why this happens, lets take an example.
List<int> object1 = new List<int>();
object1.Add(1);
object1.Add(2);
List<int> object2 = object1;
object1.Add(3);
// at this time, object2 also has an element 3.
Console.WriteLine(string.Join(",", object2));
output:
1,2,3 (instead of 1,2 that you'd normally expect)
object1 never gets assigned the "value" of object2. object1 will get "reference" of the object2 and anywhere in code when you change values of object1, object2 will automatically get updated.
Fix for that could be
List<int> object2 = object1;
object1 = new List<int>(); // re-initialized
object1.Add(3);
// object1 has only 1 element
// object2 has 2 elements.
To resolve this, you create a new object or re-initialize the object to get a new reference and then use that for later assignments.
Your code:
List<List<List<int>>> wireCoords = new List<List<List<int>>>();
List<int> coord ;
for(int i = 0; i < inputSplits.Length; i++)
{
coord = new List<int>();
coord.Add(0);
coord.Add(0);
wireCoords.Add(coord);
}
Hope it helps.
Adding to extensive explanation of the issue by #Jawad, here is how you can do that with LINQ in more concise and functional way:
List<List<List<int>>> wireCoords = inputSplits
.Select(_=> new List<int>(){0,0})
.Select(coords=> new List<List<int>>(){coords})
.ToList();
I'm trying to populate fields in one list with values from another list. I'm having trouble figuring out how to avoid the Argument Out of Range exception in the new List. I tried initializing the size of the new list to myObjectA.Count but then read that this won't actually initialize the list of that size like an array would. I'm a little stuck and was hoping for some assistance. Thanks
List<objectA> myObjectA =_GetList(id);
List<objectB> myObjectB = new List<objectB>();
for (var i=0; i < myObjectA.Count; i++)
{
myObjectB[i].Comments = myObjectA[i].Comments;
}
Because myObjectB is an empty list. You are looping through the myObjectA list which might have one more item and in the first iteration of the loop it will try to execute code like
myObjectB[0].Comments = myObjectA[0].Comments;
Which will crash because there is no items in the myObjectB list and you are trying to access the first item(zeroth index), hence getting the Out of Range exception ! specifically the Index was out of range. Must be non-negative and less than the size of the collection. exception
Assuming both objectB and objectA has Comments property of same type, you can loop through the myObjectA list and for each item, create a new objectB object and add to the list (which was originally initalized as the empty list) using the Add method.
List<objectB> myObjectB = new List<objectB>();
for (var i=0; i < myObjectA.Count; i++)
{
var b = new objectB(); //create the object
b.Comments = myObjectA[i].Comments; // map the property values
myObjectB.Add(b); //add the object to the list
}
The above foreach code can be made to a one liner with LINQ projection
var bList = myObjectA.Select(x => new objectB { Comments = x.Comments }).ToList();
The variable bList will be a list of objectB objects.
You can do like this :
for (var i = 0; i < myObjectA.Count; i++)
{
myObjectB.Add(new objectB()
{
Comments = myObjectA[i].Comments
});
}
This way, with each iteration it'll add new objectB into myObjectB list.
With Linq, you can shorten your code :
myObjectB = myObjectA.Select(x => new objectB { Comments = x.Comments }).ToList();
There is a array list that contain generic lists. How can i access the variables that in generic list? But i want to access the variables via the array list.
ArrayList TheList = new ArrayList();
List<NewType>[] GenericLists = new List<NewType>[4];
GenericLists[0].Add(variable);
.
.
.
for (int i = 0; i < 4; i++)
{
TheList.Add(GenericLists[i]);
}
How can i print the variables via the Array list?
You need to iterate over the items of your ArrayList and cast each item to List<NewType> then you can iterate over the items in the lists and display them or whatever you want...
foreach(var list in TheList)
{
var currentList = (List<NewType>)list;
...
}
Or you can use Linq methods to cast them:
foreach(var list in TheList.Cast<NewList>())
These assumes that all items in the array list are of type NewList. Otherwise you will get an InvalidCastException at runtime. To avoid this you can use is or as operators to check if the type is NewList, or you can use OfType method which does this for you:
foreach(var list in TheList.OfType<NewList>())
I have a line of code like this:
List<string>[] apples = new List<string>()[2];
Its purpose is simply to create an array of List objects. When I try to compile my code, the above line generates this error:
Cannot implicitly convert type 'string' to 'System.Collections.Generic.List[]
I haven't been able to find much on the subject of creating an array of List objects (actually only this thread), maybe because no search engines will search for brackets.
Is the only way to create a collection of Lists to put them in another list, like below?
List<List<string>> apples = new List<List<string>>(); //I've tried this and it works as expected
Thanks for any suggestions, I'm really just curious as to why the first line of code (the List[] example) doesn't work.
You can do this. The syntax would be:
List<string>[] apples = new List<string>[2];
Note that this only allocates an array of references - you'll need to actually construct the individual list elements before you use them:
List<string>[] apples = new List<string>[2];
apples[0] = new List<string>();
apples[1] = new List<string>();
Alternatively, you can use the collection initialization syntax (works well for small numbers of fixed elements), ie:
List<string>[] apples = new[] { new List<string>(), new List<string>() };
Try this:
List<string>[] apples = new List<string>[2];
You do the initialization of each list afterwards:
apples[0] = new List<string>();
var listArray = new List<string>[2];
for (var i = 0; i < listArray.Length; i++)
{
listArray[i] = new List<string>();
}
If I have:
List<string> myList1;
List<string> myList2;
myList1 = getMeAList();
// Checked myList1, it contains 4 strings
myList2 = getMeAnotherList();
// Checked myList2, it contains 6 strings
myList1.Concat(myList2);
// Checked mylist1, it contains 4 strings... why?
I ran code similar to this in Visual Studio 2008 and set break points after each execution. After myList1 = getMeAList();, myList1 contains four strings, and I pressed the plus button to make sure they weren't all nulls.
After myList2 = getMeAnotherList();, myList2 contains six strings, and I checked to make sure they weren't null... After myList1.Concat(myList2); myList1 contained only four strings. Why is that?
Concat returns a new sequence without modifying the original list. Try myList1.AddRange(myList2).
Try this:
myList1 = myList1.Concat(myList2).ToList();
Concat returns an IEnumerable<T> that is the two lists put together, it doesn't modify either existing list. Also, since it returns an IEnumerable, if you want to assign it to a variable that is List<T>, you'll have to call ToList() on the IEnumerable<T> that is returned.
targetList = list1.Concat(list2).ToList();
It's working fine I think so. As previously said, Concat returns a new sequence and while converting the result to List, it does the job perfectly.
It also worth noting that Concat works in constant time and in constant memory.
For example, the following code
long boundary = 60000000;
for (long i = 0; i < boundary; i++)
{
list1.Add(i);
list2.Add(i);
}
var listConcat = list1.Concat(list2);
var list = listConcat.ToList();
list1.AddRange(list2);
gives the following timing/memory metrics:
After lists filled mem used: 1048730 KB
concat two enumerables: 00:00:00.0023309 mem used: 1048730 KB
convert concat to list: 00:00:03.7430633 mem used: 2097307 KB
list1.AddRange(list2) : 00:00:00.8439870 mem used: 2621595 KB
I know this is old but I came upon this post quickly thinking Concat would be my answer. Union worked great for me. Note, it returns only unique values but knowing that I was getting unique values anyway this solution worked for me.
namespace TestProject
{
public partial class Form1 :Form
{
public Form1()
{
InitializeComponent();
List<string> FirstList = new List<string>();
FirstList.Add("1234");
FirstList.Add("4567");
// In my code, I know I would not have this here but I put it in as a demonstration that it will not be in the secondList twice
FirstList.Add("Three");
List<string> secondList = GetList(FirstList);
foreach (string item in secondList)
Console.WriteLine(item);
}
private List<String> GetList(List<string> SortBy)
{
List<string> list = new List<string>();
list.Add("One");
list.Add("Two");
list.Add("Three");
list = list.Union(SortBy).ToList();
return list;
}
}
}
The output is:
One
Two
Three
1234
4567
Take a look at my implementation. It's safe from null lists.
IList<string> all= new List<string>();
if (letterForm.SecretaryPhone!=null)// first list may be null
all=all.Concat(letterForm.SecretaryPhone).ToList();
if (letterForm.EmployeePhone != null)// second list may be null
all= all.Concat(letterForm.EmployeePhone).ToList();
if (letterForm.DepartmentManagerName != null) // this is not list (its just string variable) so wrap it inside list then concat it
all = all.Concat(new []{letterForm.DepartmentManagerPhone}).ToList();