i have a nested list that contains a set of lists, some of these lists are duplicated, i wanna just make a second list without duplicated lists. i tried this :
List<List<string>> liste1 = new List<List<string>>();
List<List<string>> liste2 = new List<List<string>>();
List<string> l1 = new List<string> { "a", "b", "c" };
List<string> l2 = new List<string> { "h", "x", "g" };
List<string> l3 = new List<string> { "a", "b", "c" };
List<string> l4 = new List<string> { "z", "t", "n" };
liste1.Add(l1);
liste1.Add(l2);
liste1.Add(l3);
liste1.Add(l4);
foreach (List<string> lis in liste1)
{
if(!liste2.Contains(lis))
{
liste2.Add(lis);
}
}
it seems easy but its not working, any help will be appreciated. Thx.
Using Linq, you could achieve this.
You could take help of extension methods and look for SequentialEqual of two lists. If the order is not important use Except extension (something like ...s.Except(x).Any()).
var liste2= liste1.Where((x,i)=> !liste1.Skip(i+1).Any(s=>s.SequenceEqual(x)));
Check this Demo
You are checking for reference equality. Instead of using Contains try this substitution
//if (!liste2.Contains(lis))
if(!liste2.Any(subList => subList.SequenceEqual(lis)))
SequenceEqual is an extension method on IEnumerable<T>. I think you will need a using statement importing the System.Linq namespace.
If you dont want to test that the child lists are not sequence-equal, but set-equal (i.e. order is not important), then consider using an implementation of ISet<T> like HashSet<int> instead of List<int>.
Related
My idea is to use a new list (List1) and compare it with another list (List2) and create a new list (List3) that exclude all common elements in both lists and results on the non common elements. The difficult thing (to me) is that List1 and List2 elements are not a true match. List1 elements might be part of List2 elements, but not a truly match. Using exclude does not seem to allow the use of IndexOf to compare the two list elements.
Does anyone have an idea how to achieve this?
Thanks in advance.
Assuming you have List1 and List2. Below is the simplest way to compare elements in two lists.
IList<string> List3 = new List<string>();
foreach (var item1 in List1)
{
foreach(var item2 in List3)
{
if (item1 == item2)
{
List3.Add(item1);
}
}
}
My idea is to use a new list (List1) and compare it with another list
(List2) and create a new list (List3) that exclude all common elements
in both lists and results on the non common elements.
From Comments
I need to compare each element in both lists List1 element exists in
List2 element (both strings).
One of the easiest ways to find unique from two lists
var List1 = new List<string>() { "a", "b", "c", "d" };
var List2 = new List<string>() { "a", "e", "f", "g", "c","z" };
var List3 = new List<string>();
List3.AddRange(List1.Except(List2));
List3.AddRange(List2.Except(List1));
List3.ForEach(l=>Console.WriteLine(l));
How about this:
List commonElements = new List<string>();
foreach (var smallString in SmallList)
{
if (large.Any(x => x.Contains(smallString)))
{
// Add to common elements
commonElements.Add(smallString);
}
}
Consider this code:
string[] myCollection = { "a", "b", "c", "d" };
string[] anotherCollection = { "c", "d" };
I want to test that myCollection does not contain any item of anotherCollection. How can I achieve that in NUnit?
I tried these:
CollectionAssert.DoesNotContain(anotherCollection, myCollection);
Assert.That(myCollection, Has.No.Member(anotherCollection));
...but the problem is that these functions operate on a single entity and I did not find any way to let them work with arrays.
To assert that a collection does not contain any of a set of items, we can check that the intersection of another collection is empty using LINQ:
string[] subject = { "a", "b", "c", "d" };
string[] forbidden = { "c", "d" };
Assert.IsEmpty(subject.Intersect(forbidden));
// Or:
Assert.That(subject.Intersect(forbidden), Is.Empty);
The test shown above will fail because both collections contain the values "c" and "d".
If we want the test to fail only when the collection contains all of the prohibited items:
Assert.That(subject.Intersect(forbidden), Is.Not.EquivalentTo(forbidden));
// Or:
Assert.That(subject, Is.Not.SupersetOf(forbidden));
I have two lists:
List<string> list1 = new List<string>(){ "a", "b", "c", "d" };
List<string> list2 = new List<string>(){ "b", "d", "e" };
I want to find all items of list1 that match the items in list2, and generate a List list3 that contains:
{ false, true, false, true }
How can I go about that?
Thanks in advance,
Wavy
This is all it takes:
list1.Select(str => list2.Contains(str)).ToList();
#Balazs answer is correct, but you should know that Contains operation on list is O(n) operation. And if lists are pretty big, then creating new list will be O(n*m) operation, which might be pretty slow. If you want to check whether some value is among other values, best way is having some hash-based structure which has O(1) for Contains operation. So, just put second list values to HashSet
var hashSet = new HashSet<string>(list2);
var result = list1.Select(hashSet.Contains).ToList();
I would like to add arrays to a list or multidimensional array (not all at once...). But I dont really understand why this should be that hard.
Lets say I have this:
string[] a = { "h", "b"};
string[] b = { "c", "a", "i" };
string[] c = { "out", "in", "file", "test" };
ArrayList x = null;
x.Add(a); //error: Object reference not set to an instance of an object.
x.Add(b);
x.Add(c);
Can I use instead of the ArrayList maybe
string[,] x = null;
But there is no option to .Add
Lets say I have an unknown amount of string[]´s with an unknown size - how do I add them to a List/multidimensional array? And again: I would like to add these string[]´s one by one. Any ideas?
You are getting an NullReferenceException because your list is not initialized:
string[] a = { "h", "b"};
string[] b = { "c", "a", "i" };
string[] c = { "out", "in", "file", "test" };
IList<string[]> x = new List<string[]>;
x.Add(a);
x.Add(b);
x.Add(c);
This assumes that you are constructing a 2-D structure. If you would like to "flatten" your arrays into a single list of strings, create a list, and use its List.AddRange method instead.
you haven't made an instance of the ArrayList you want to store the string arrays in. Try adding
ArrayList x = new ArrayList();
x.Add(a);
...
...
ArrayList x = null;
x.Add(a);
That would work if:
You create an instance of ArrayList:
ArrayList x = new ArrayList();
all you were doing was to declare a local variable.
You are careful to separate ArrayList.Add from ArrayList.AddRange. The former adds a single object. In your case the first element (after the first Add) would be itself an array. To access the "h" would need x[0][0]. AddRange takes each passed collection element in term and adds it to the collection. Thus getting the "h" would be x[0] and "b" would be x[1].
I think you want:
string[] a = { "h", "b"};
string[] b = { "c", "a", "i" };
string[] c = { "out", "in", "file", "test" };
ArrayList x = new ArrayList();
x.AddRange(a);
x.AddRange(b);
x.AddRange(c);
The keyword null essentially means "no object". Therefore when you write x.Add(a) you are trying to call the Add method on something that isn't there.
You need to initialize your list first, which puts something in the box labelled x:
ArrayList x = new ArrayList();
You can now call x.add(a) and your code will work as expected.
You are missing new for ArrayList so you should do it like this:
ArrayList x = new ArrayList();
x.AddRange(a);
x.AddRange(b);
x.AddRange(c);
You can't can't use array in Add method , you will not get any compile error but then while you will access the object you will get just ToString on type that means if you say:
string[] a = { "h", "b"};
x.Add(a);
and then try to loop through the elements like:
foreach (var item in x)
{
Console.WriteLine(item);
}
you will the result: System.String[] and I hope you don't want that, so you need to use AddRange method which takes an argument of type ICollection, so you say:
x.AddRange(a);
and if you do a loop on array list like:
foreach (var item in x)
{
Console.WriteLine(item);
}
you will get the output,
h
b
One way to do it is:
List<List<string>> list = new List<List<string>>();
list.Add(new List<string>(){
"str1", "str2", "..."
});
be sure to include: using System.Collections.Generic;
I have a bunch of string data and I can loop through it one by one. What's a good collection (and how to implement it) so that I only get the distinct strings?
The client I am doing this for doesn't even use .NET 3.5 so .Distinct is out. They use .NET framework 2.0.
And I am reading the list one at a time and don't know how many records it will have until I'm done.
One way is using Distinct to make your strings unique:
List<string> a = new List<string>();
a.AddRange(new string[] { "a", "b", "a", "c", "d", "b" });
List<string> b = new List<string>();
b.AddRange(a.Distinct());
Another resource on LINQ's Distinct: http://blogs.msdn.com/b/charlie/archive/2006/11/19/linq-farm-group-and-distinct.aspx
Another way: use a HashSet as others suggested;
HashSet<string> hash = new HashSet<string>(inputStrings);
Have a look for this link, to see how to implement it in .net 2.0: https://stackoverflow.com/a/687042/284240
If you're not on 3.5, you also can do it manually:
List<string> newList = new List<string>();
foreach (string s in list)
{
if (!newList.Contains(s))
newList.Add(s);
}
// newList contains the unique values
Another solution (maybe a little faster):
Dictionary<string,bool> dic = new Dictionary<string,bool>();
foreach (string s in list)
{
dic[s] = true;
}
List<string> newList = new List<string>(dic.Keys);
// newList contains the unique values
https://stackoverflow.com/a/1205813/284240
If you're using .Net 3.5 or above, put the strings in a List<> and use the linq method Distinct().
using System.Linq;
IEnumerable<string> strs = new List<string>(new[] { "one", "two", "three", "one" });
var distinct = strs.Distinct();
In .Net 2.0 you have no choice but to do it manually.
Perhaps I'm being dense and not fully understanding the question but can't you just use a regular List and just use the .Contains method to check if each string exists in the list before adding it in the loop? You might need to keep an eye on performance if you have a lot of strings.