I want to compare elements inside a single List in C#. I need to check whether same data is there in list or not . Can anybody help me with this?
You can try this, for example:
var collection = new List<double>(new double[] { 10, 20, 11, 10, 20, 44 });
var info = collection.GroupBy(e => e).ToDictionary(e => e.Key, e => e.Count());
Here info contain a double value as a key and number of this number in collection as value.
And this construction you can use with any type of List elements.
You could use the LINQ extention methods
here is an example of LINQ comparing lists:
list<string> arr1 = new list<string>(){ "A", "b", "C," };
list<string> arr2 = new list<string>(){ "A", "b", "C," };
Compare the above arrays with the SequentialEqual() Method
bool result = arr3.SequentialEqual(arr2);
The Boolean result will contain true as the items in both lists are equal
Hope this helps
If you just want to know if there is more than one item in the list has the same value you can use this function..
public bool HasSameData<T>(List<T> myList)
{
return myList.Distinct().Count() != myList.Count();
}
note that this will work with any type.
void Main()
{
var myList = new List<int> {1,2,3,4,5,6,7,8,9};
var myList2 = new List<int> {1,1,3,4,5,6,7,8,9};
Console.WriteLine(HasSameData(myList));
Console.WriteLine(HasSameData(myList2));
var myList3 = new List<String> {"hello","world","foo","bar"};
var myList4 = new List<String> {"hello","foo","foo","bar"};
Console.WriteLine(HasSameData(myList3));
Console.WriteLine(HasSameData(myList4));
Console.ReadLine();
}
OUTPUT:
False
True
False
True
Related
I basically want to know if a string array from one list exists in another list of string array
So for example:
List 1:
{"A", "R1"}
{"A", "R2"}
List 2:
{"A", "R1"}
{"B", "R1"}
{"B", "R2"}
Then If I loop in List 1 to check whether it exists in List 2 the results will be:
true
false
I want to do it in LINQ if possilbe
You can use
Any and SequenceEqual
for this.
using System.Collections.Generic;
List<string[]> testSet = new List<string[]>
{
new string[] { "A", "R1" },
new string[] { "A", "R2" }
};
List<string[]> resultSet = new List<string[]>
{
new string[] { "A", "R1" },
new string[] { "B", "R1" },
new string[] { "B", "R2" }
};
// Checks if the value is found anywhere in the list
bool IsArrayInList(string[] value, List<string[]> list)
{
return list.Any(value.SequenceEqual);
}
foreach (var val in testSet)
{
Console.WriteLine(IsArrayInList(val,resultSet));
}
Console.ReadLine();
I would suggest a combination of .Any() and .SequenceEqual() or .All()
Example:
var list1 = new string[][]
{
new string[] { "A", "R1" },
new string[] { "A", "R2" },
};
var list2 = new string[][]
{
new string[] { "A", "R1"},
new string[] { "B", "R1"},
new string[] { "B", "R2"},
};
var itemToFind = list1.First();
// Option 1
var isInList2 = list2.Any(i => i.SequenceEqual(itemToFind));
// Option 2
var isInList2Option2 = list2.Any(item => item.All(innerItem => itemToFind.Contains(innerItem)));
As-needed, you can improve these to account for ordering, case-insensitivity, exact number of arguments, etc...
Option 1 will find any matches where the inner sequence is in the same order, same-casing as what you are looking for.
Option 2 will find any matches where the inner sequence contains all of the values of the sequence you are checking for.
Hopefully this points you in the right direction at least.
Removing the code as it is private one
List<string> list1 = new List<string> { "0186264-9-2019-019", "0186264-9-2019-020" };
List<string> list2 =new List<string> { "0186264-9-2019-020" };
var d = list1.Except(list2).Any() ;
You can use Except to find the difference between the 2 sets (while optimizing lookups).
bool allElements = !list1.Except(list2).Any();
list1.Except(list2) returns the collection of items in list1 that are in list2. If it does not contain any elements, list2 has all the items of list1 (and maybe other items not in list1).
You can use All method:
var haveAll= list1.All(element=> list2.Contains(element))
You can do using linq expression.
Here code reference.
List<string> list1 = new List<string> { "0186264-9-2019-019", "0186264-9-2019-020" };
List<string> list2 = new List<string> { "0186264-9-2019-020" };
List<string> Common = list1.Where(c => list2.Contains(c)).ToList();
As per your comment you can do using except method.
List<string> list1 = new List<string> { "0186264-9-2019-019", "0186264-9-2019-020" };
List<string> list2 = new List<string> { "0186264-9-2019-020" , "0186264-9-2019-019" };
if (list1.Except(list2).Any())
{
// All list 1 values not present in list 2
}
else
{
// All list 1 values present in list 2
}
Is there a easy way to do this using linq?
I want to check and return true or false, whether any string from list1 contains a string from array1. In the below example that would be string2value and i would want to return true.
Also similarly i want to check whether any array1 would contain a string from list1. That would be string1blah and so that would return true as well. Thanks!
List<string> list1 = new List<string>{"string1","string2value"};
string[] array1 = new string[2] {"string1blah","string2"};
I have a couple of versions, but it does not work all the time.
array1.ToList().Any(a=>list1.Contains(a))
list1.Any(l=>array1.ToList().Contains(l))
You can try this:
var result= list1.Where(s=>array1.Any(s1=>s.Contains(s1)));
Per each string in the list1, you see if there is an element in array1 that is contained in s string.
The way your question is worded it is hard to understand what you want.
If you want all the strings in one list which are substrings of an element in the other list, then this should work:
var substrings = myList.Where(bigstring => myArray.Any(substring => bigstring.Contains(substring)));
If you just want to know whether such an element exists, then do this:
bool myCondition = myList.Any(bigstring => myArray.Any(substring => bigstring.Contains(substring)));
If you're wanting pretty linq, you can do:
static void Main(string[] args)
{
var list1 = new List<string> { "string1", "string2value" };
var array1 = new string[] { "string1blah", "string2" };
var result = from sl in list1
from sa in array1
where sl.Contains(sa) || sa.Contains(sl)
select new { sl, sa };
foreach (var x in result)
{
Console.WriteLine(x);
}
}
Which gives nice output
{ sl = string1, sa = string1blah }
{ sl = string2value, sa = string2 }
You can also use linq query expressions if you want.
Give this code:
List<string> list1 = new List<string> { "string1", "string2value" };
string[] array1 = new string[2] { "string1blah", "string2" };
I want to check and return true or false, whether any string from list1 contains a string from array1. In the below example that would be string2value and i would want to return true.
You can do it like this:
var result = from l1 in list1
from a1 in array1
where l1.Contains(a1)
select l1; // Or select true if you want to just return true
Also similarly i want to check whether any array1 would contain a string from list1. That would be string1blah and so that would return true as well. Thanks!
You can modify the above to achieve it like this:
var result = from l1 in list1
from a1 in array1
where a1.Contains(l1)
select a1;
To return true or false (as you've mentioned in the OP Comments), you would modify the call to count the items contained, and if greater than 0, return true.
EDIT Thanks Dax Fohl
var list1 = new List<string> {"Test1", "Test2", "Test3", "Test4"};
var array1 = new string[] {"Test3", "Test4", "Test5", "Test6"};
var result = list1.Any(s => array1.Any(s.Contains));
in linq, is it possible to combine many lists (of the same type), such that two lists,
list 1 = {a,b,c} and list 2 = {x,y,z}
turns into {[1,a] , [1,b] , [1,c] , [2,x] , [2,y] , [2,z] }
where [] represents a pair containing a "list identifier"
The problem is from having decks of arbitrary cards, where each deck is a list in a collection of lists.
I'm trying to create a query such that I can select only cards in a certain deck, or cards similar to 2 or more decks.
This is probably a duplicate question, but I don't know how to search for the question further then I already have.
List<List<int>> lists;
var combined = lists.Select((l, idx) => new { List = l, Idx = idx })
.SelectMany(p => p.List.Select(i => Tuple.Create(p.Idx + 1, i)));
var list1 = new List<string>() {a,b,c};
var list2 = new List<string>() {x,y,z};
var combined = list1.Select(x => new { id = 1, v = x }).Concat(list2.Select(x => new { id = 2, v = x }));
Normally I'd suggest Enumerable.Zip for combining multiple lists, however you seem to actually want to concatenate multiple lists with a list counter.
public IEnumerable<Tuple<int,T>> Combine<T>(params IEnumerable<T>[] lists) {
return lists.Select((x,i) => x.Select(y => Tuple.Create(i+1,y))).SelectMany (l =>l);
}
UPDATE
Completely missed that SelectMany has the index option so the above code can be written as
public IEnumerable<Tuple<int,T>> Combine<T>(params IEnumerable<T>[] lists) {
return lists.SelectMany((x,i) => x.Select(y => Tuple.Create(i+1,y)));
}
Then you can do
var list1 = new List<string> { "a", "b", "c" };
var list2 = new List<string> { "x", "y", "z" };
var combined = Combine(list1,list2);
Combined will be enumerable of tuples, with Item1 being the list index identifier (starting at 1) and Item2 being the value.
This method will handle multiple lists so you could just as easily call it with:
var list3 = new List<string> { "f", "g" };
var combined = Combine(list1,list2,list3);
You can merge the lists like:
var first = new List<string> {"a","b","c"};
var second = new List<string> {"x","y","z"};
var merged = first.Select(item => new { ListIndex = 1, Value = item}).ToList();
merged.AddRange(second.Select(item => new { ListIndex = 2, Value = item});
//or use concat
var merged = first.Select(item => new { ListIndex = 1, Value = item});
.Concat(second.Select(item => new { ListIndex = 2, Value = item});
Alternatively if you have the sources in something like:
List<List<string>> lists = new List<List<string>>
{
new List<string> {"a","b","c"},
new List<string> {"x","y","z"}
};
you can do:
var merged = lists.SelectMany((item, index) =>
item.Select(s => new { ListIndex = index, Value = s}));
Note that this will produce a 0-based list, so if you really need a 1-base list, just do ListIndex = index +1.
Also, if you will use this a lot, I would create it as an specific entity, something like
struct ListIdentValue
{
public int ListIndex {get; private set;}
public string Value {get; private set;}
public ListIdentValue(int listIndex, string value) {...}
}
Try using Concat
new[] {'a','b','c'}
.Select(v=>new Tuple<int,char>(1, v))
.Concat(
new[] {'x','y','z'}.Select(v=>new Tuple<int,char>(2, v))
)
string[] a = { "a", "b", "c" };
string[] b = { "x", "z", "y" };
var t =
(
from ai in a
select new { listNo = 1, Item = ai }
).Union
(
from bi in b
select new { listNo = 2, Item = bi }
);
or
var t =
(
from ai in a
select new object[] { 1, ai }
).Union
(
from bi in b
select new object[] { 2, bi }
);
I have two lists and one of them has 5 elements and the other one has 4 elements. They have some same elements but they have different elements too. I want to create a list with their different element. How can i do it?
Note: 5 elements list is my main list.
What about this?
var list1 = new List<int>( new []{1,2,3,4,5});
var list2 = new List<int>( new []{1,3,4});
var list3 = list1.Except( list2);
In this case, list3 will contain 2 and 5 only.
EDIT
If you want the elements from both sets that are unique, the following code should suffice:
var list1 = new List<int>( new []{1,2,3,4,5});
var list2 = new List<int>( new []{1,3,4,7});
var list3 = list1.Except(list2).Union(list2.Except(list1));
Will output 2,5 and 7.
If you're curious, the opposite of this is called Intersect
string[] collection1 = new string[] { "1", "7", "4" };
string[] collection2 = new string[] { "6", "1", "7" };
var resultSet = collection1.Intersect<string>(collection2);
foreach (string s in resultSet)
{
Console.WriteLine(s);
}