Adding list object inside a list C# - c#

I'm new in c#. I just want to ask if it is possible to insert a list object inside a c# list just like in python? C# addrange only insert multiple item at once but not a list object.
For example:
lst = [[1,2,3],[4,5,6],[7,8,9]]

Yes, but is much more verbose than python.
As some comments already answered, you can use a List of List to create something like your python example:
List<List<int>> listOfLists = new List<List<int>>() { new List<int>() {1,2,3}, new List<int>() {4,5,6}, new List<int>() {7,8,9}};
You can also make a list of different objects just declaring it a List of Objects:
List<object> listOfObjects = new List<object>();
listOfObjects.Add(new List<int>() { 1, 2, 3 }); // Adding list of int
listOfObjects.Add("text"); // Adding string
listOfObjects.Add(new float[] { 1.42f, 51.7f}); // Adding array of float
listOfObjects.AddRange(listOfObjects); // Duplicating all the elements of listOfObjects
listOfObjects.AddRange(listOfLists); // Adding all elments of the list listOfLists
List AddRange is just a way of adding many elements at once inside a list.

Related

Addition and deletion of sub list from main list

I have two lists such as Main List of type <T> and Sub List of same type
Now there are two conditions where
in one condition I want to remove the entire Sub List items from Main List and
in another condition just need to add all sub list items inside the Main list.
So far I have achieved this using the foreach loop, but now I just want to do it using LINQ concept.
Is there any way?
Thank you for posting your ideas, got the exact answer from #Sweeper idea, I just resolve this by using int type Lists, Here I am posting my answer,
`List<int> MainList = new List<int>() { 1, 2, 3, 4, 5 };
List<int> SubList = new List<int>() { 4,5};
MainList=MainList.Except(SubList).ToList();
MainList = MainList.Union(SubList).ToList();`
As per my understanding of your question,
List<Object> x = new List<Object>();
List<Object> y = new List<Object>();
if (somecondition)
{
x = x.Except(y).ToList();
}
else if (anotherCondition)
{
x = x.Concat(y).ToList();
}

Difference between Add and AddRange in arrayList c#

Can anyone tell when to use Add() and AddRange() of ArrayList?
If you want to add a large number of values at one time, use AddRange.
If you are only adding a single value or adding values infrequently, use Add
Difference Between Add and AddRange
Add---------It is used to add the item into the list one by one.
AddRange-----------It is used to add the bulk of list item into the another list.
List<string>list1=new List<string>();//using Add
List<string>list2=new List<string>();//using AddRange
list1.Add("Malathi");
list1.Add("Sandhiya");
list1.Add("Ramya");
list1.Add("Mithra");
list1.Add("Dharshini");
list2.AddRange(list1);
output:
//The output of list1 contains
Malathi,
Sandhiya,
Ramya,
Mithra,
Dharshini
//The output of list2 Contains
Malathi,
Sandhiya,
Ramya,
Mithra,
Dharshini
C# List class represents a collection of a type in C#. List.Add(), List.AddRange(), List.Insert(), and List.InsertRange() methods are used to add and insert items to a List.
AddRange - AddRange adds an entire collection of elements. It can replace tedious foreach-loops that repeatedly call Add on List.
public virtual void AddRange (System.Collections.ICollection c);
Add - Add method adds an object to the end of the List.
public virtual int Add (object value);
Example: Now set an array of elements to be added to the list.
// array of 4 elements
int[] arr = new int[4];
arr[0] = 500;
arr[1] = 600;
arr[2] = 700;
arr[3] = 800;
Use the AddRange() method add the entire collection of elements in the list −
List<int> list = new List<int>();
list.AddRange(arr);
But if you want to use List.Add() method,
List<int> list = new List<int>();
list.Add(100);
list.Add(200);
list.Add(300);
list.Add(400);
For details, you can check Insert an Item into a C# List
If You want to add single variable in List, then Add() is used.
But if you want to add List or multiple variable in List, then AddRange() can be used
var t = (from t1 intable1
join t2 in table2 on t1.t1id equals t2.t2id
select new ABCViewModel
{
FirstName = t1.firstname,
LastName = t1.Lastname
})
.where(t2.age>35)
.ToList();
var s = (from t1 intable1
join t2 in table2 on t1.t1id equals t2.t2id
select new ABCViewModel
{
FirstName = t1.firstname,
LastName = t1.Lastname
})
.where(t2.age < 35)
.ToList();
t.AddRange(s);
return t;
It will add result of List s to List t along with result of List t.
Difference b/w Add() and AddRange() methods is very straight forward
Add() is used to add an element in the list.
AddRange() is used to add a range of elements(multiple elements) at once in the list.
Note: Multiple elements can be another entire Array, HashTable, SortedList, ArrayList, BitArray, Queue, and Stack.
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
//create the first arraylist
ArrayList arraylist1 = new ArrayList();
arraylist1.Add(5);
arraylist1.Add(7);
//create the second arraylist
ArrayList arraylist2 = new ArrayList();
arraylist2.Add("Five");//add the single value at time to the arraylist
arraylist2.Add("Seven");//add the single value at time to the arraylist
//perform AddRange method
arraylist1.AddRange(arraylist2);//adding the arraylist as bulk in another arraylist
// Display the values.
foreach (object i in arraylist1)//iterating the arraylist1 value to object
{
Console.WriteLine(i);
}
}
}
}

Alternative to RemoveAt and Insert list items

I am looking for a better data structure or method to simply replace an object in an dynamic array. It seems like list is the choice, however I read and notice that the performance of RemoveAt and Insert is not as good as I had hoped.
Let me elaborate on what I am trying to achieve:
List1
List item 1
List item 2
List item 3
List2
List item 1
List item 2
Null
Both list uses the same object types. I want to replace the null list item of List2 with List1[1] -- List item 1 clone. I use a clone so the value of the copied list item is a separate instance.
I also want to replace list item 2 of List2 with a clone of list item 1 of List2.
Here is some example code of what I am trying to achieve:
projCraneVertices.RemoveAt(projCraneVertices.Count - 4);
projCraneVertices.Insert((projCraneVertices.Count - 3), realCraneVertices[botPoint].clone());
projCraneVertices.RemoveAt(projCraneVertices.Count - 3);
projCraneVertices.Insert((projCraneVertices.Count - 2), projCraneVertices[botPoint].clone());
projCraneVertices.RemoveAt(projCraneVertices.Count - 2);
projCraneVertices.Insert((projCraneVertices.Count - 1), realCraneVertices[topPoint].clone());
projCraneVertices.RemoveAt(projCraneVertices.Count - 1);
projCraneVertices.Insert((projCraneVertices.Count), projCraneVertices[topPoint].clone());
I also want to replace list item 2 of List2 with a clone of list item
1 of List2.
Well, you can do it simpler like this:
proCraneVertices[2] = realCraneVertices[1].Clone();
From what I can understand, you want a Replace method. Try this extension:
public static class Extensions
{
public static void Replace<T>(this IList<T> list, int index, T item)
{
list[index] = item;
}
}
Call like:
List<int> ints = new List<int>() { 1, 2, 3 };
List<int> ints2 = new List<int>() { 4, 5, 6 };
ints.Replace(0, ints2[0]);
The above will make the first list - 4, 2, 3.
using List of T will solve you problem of removeAt and inset this uses Array under the hood and will expose some good functions to you that will help to ridoff these anoing methods.
you can use some of function provided by List like below.
Replace // Replact the item from one item to another item
List of T Class

List<List<int>> Remove() method

I'd like to use Remove() method on list of lists, but it's not working for me.
Simple example should say everything:
List<List<int>> list = new List<List<int>>();
list.Add(new List<int> { 0, 1, 2 });
list.Add(new List<int> { 1, 2 });
list.Add(new List<int> { 4 });
list.Add(new List<int> { 0, 1, });
list.Remove(new List<int> { 1, 2 });
If I use RemoveAt(1) it works fine but Remove() not.
It is obviously the same reason that this code returns false:
List<int> l1 = new List<int>();
List<int> l2 = new List<int>();
l1.Add(1);
l2.Add(1);
bool b1 = l1 == l2; // returns False
bool b2 = l1.Equals(l2); // returns False too
So it seems to me that I cannot simply compare two lists or even arrays. I can use loops instead of Remove(), but there must be easier way.
Thanks in advance.
The problem is that List<T> doesn't override Equals and GetHashCode, which is what List<T> will use when trying to find an item. (In fact, it will use the default equality comparer, which means it'll use the IEquatable<T> implementation if the object implements it, and fall back to object.Equals/GetHashCode if necessary). Equals will return false as you're trying to remove a different object, and the default implementation is to just compare references.
Basically you'd have write a method to compare two lists for equality, and use that to find the index of the entry you want to remove. Then you'd remove by index (using RemoveAt). EDIT: As noted, Enumerable.SequenceEqual can be used to compare lists. This isn't as efficient as it might be, due to not initially checking whether the counts are equal when they can be easily computed. Also, if you only need to compare List<int> values, you can avoid the virtual method call to an equality comparer.
Another alternative is to avoid using a List<List<int>> in the first place - use a List<SomeCustomType> where SomeCustomType includes a List<int>. You can then implement IEquatable<T> in that type. Note that this may well also allow you to encapsulate appropriate logic in the custom type too. I often find that by the type you've got "nested" collection types, a custom type encapsulates the meaning of the inner collection more effectively.
First approach:
List<int> listToRemove = new List<int> { 1, 2 };
list.RemoveAll(innerList => innerList.Except(listToRemove).Count() == 0);
This also removes the List { 2, 1 }
Second approach (preferred):
List<int> listToRemove = new List<int> { 1, 2 };
list.RemoveAll(innerList => innerList.SequenceEqual(listToRemove));
This removes all lists that contain the same sequence as the provided list.
List equality is reference equality. It won't remove the list unless it has the same reference as a list in the outer list. You could create a new type that implements equality as set equality rather than reference equality (or you do care about order as well?). Then you could make lists of this type instead.
This simply won't work because you're tying to remove a brand new list (the new keyword kind of dictates such), not one of the ones you just put in there. For example, the following code create two different lists, inasmuch as they are not the same list, however much they look the same:
var list0 = new List<int> { 1, 2 };
var list1 = new List<int> { 1, 2 };
However, the following creates one single list, but two references to the same list:
var list0 = new List<int> { 1, 2 };
var list1 = list0;
Therefore, you ought to keep a reference to the lists you put in there should you want to act upon them with Remove in the future, such that:
var list0 = new List<int> { 1, 2 };
listOfLists.Remove(list0);
They are different objects. Try this:
List<int> MyList = new List<int> { 1, 2 };
List<List<int>> list = new List<List<int>>();
list.Add(new List<int> { 0, 1, 2 });
list.Add(MyList);
list.Add(new List<int> { 4 });
list.Add(new List<int> { 0, 1, });
list.Remove(MyList);
You need to specify the reference to the list you want to remove:
list.Remove(list[1]);
which, really, is the same as
list.RemoveAt(1);

C# Function Chaining

Why do i receive error in the following declaration ?
List<int> intrs = new List<int>().AddRange(new int[]{1,2,3,45});
Error :Can not convert type void to List ?
Because AddRange function does not return a value. You might need to perform this in two steps:
List<int> intrs = new List<int>();
intrs.AddRange(new int[]{1,2,3,45});
You could also use a collection initializer (assuming C# 3.0+).
List<int> intrs = new List<int> { 1, 2, 3, 45 };
Edit by 280Z28: This works for anything with an Add method. The constructor parenthesis are optional - if you want to pass thing to a constructor such as the capacity, you can do so with List<int>(capacity) instead of just List<int> written above.
Here's an MSDN reference for details on the Object and Collection Initializers.
Dictionary<string, string> map = new Dictionary<string, string>()
{
{ "a", "first" },
{ "b", "second" }
};
Because AddRange modifies the specified list instead of returning a new list with the added items. To indicate this, it returns void.
Try this:
List<int> intrs = new List<int>();
intrs.AddRange(new int[]{1,2,3,45});
If you want to create a new list without modifying the original list, you can use LINQ:
List<int> intrs = new List<int>();
List<int> newIntrs = intrs.Union(new int[]{1,2,3,45}).ToList();
// intrs is unchanged
AddRange does not return the list it has added items to (unlike StringBuilder). You need to do something like this:
List<int> intrs = new List<int>();
intrs.AddRange(new int[]{1,2,3,45});
AddRange() is declared as:
public void AddRange(object[]);
It does not return the list.
By the way in C# 3.x (not sure about 2.0) you can do either of
List<int> intrs = new List<int>{1,2,3,45};
List<int> intrs = new []{1,2,3,45}.ToList(); // with Linq extensions
Besides other answers, you can add your own extension method that will add range and return list (not that it's a good practice).
BTW, if you had already declared intrs, you could have done it with parentheses:
(intrs = new List<int>()).AddRange(new int[] { 1, 2, 3, 45 });
However, I like the initialization syntax better.
Although others have already mentioned that AddRange does not return a value, based on the samples given for alternatives it should also be remembered that the constructor of List will take an IEnumerable of T as well in addition to the code previously mentioned that is .NET 3.5+
For example:
List<int> intrs = new List<int>(new int[]{2,3,5,7});
There is yet another way.
List<int> intrs = new List<int>
{
1,
2,
3,
45
};

Categories

Resources