I have a list1 with these items:
"Test1"
"TestB"
"TestA"
and I have list2 with these items:
"Test1"
"Test2"
"Test3"
"Test4"
"Test5"
Case: list2.Test1 is the only item from list2 which occurs in list1, thats a positive case.
if list1 has ONE item of list2 then...
How can I express that with LINQ?
var count = list2.Count(x => list1.Contains(x));
or
var count = list2.Intersect(list1).Count();
Try this
Use Except:
var count = list2.Except(list1).Count();
or
var count = list2.Intersect(list1).Count();
or
var count = list2.Count(x => list1.Contains(x));
Related
I have a list of strings like
List<string> mylist = new List<string> { "US", "UK" };
and another list variable contains the values like
List<string> countries = new List<string> { "US", "AU","NL" };
I just want to split the countries list into two based on my list
ex
list1 = { "US"};
list2 = { "AU","NL" };
I tried to group the list but i failed. any help?
var results = mylist.GroupBy(item => countries.Contains(item)).ToList();
var list1 = results.First().ToList();
var list2 = results.Last().ToList();
above code return the same mylist values for list1 and list2
You can use this;
var mylist = new List<string>{ "US", "UK" };
var countries = new List<string>{ "US", "AU","NL" };
var list1 = mylist.Intersect(countries).ToList();
var list2 = countries.Except(mylist).ToList();
Edit - Figuered this out thanks to #Monofuse:
List<List<int>> list1,
list2,
list2_flattened = list2.SelectMany(x => x).ToList(); // 1d list
list1 = list1.Select(x => x.Where(y => !list2_flattened.Contains(y)).ToList()).ToList(); // 2d list (definitely not the most efficient function, but my list is constrained to a size of about 20)
Given the 2 lists:
List<List<int>> list1;
List<List<int>> list2;
How would you filter the items in List1, such that you end up with items that don't exist in list2?
forgot to mention: list1 must keep the original structure (that is List<List>, so SelectMany isn't an option)
I'm looking for a linq solution
Thanks!
If I've understood you right, and you want to exclude list2 int values from list1 you can put
var result = list1
.Select(list => list
.Where(item => !list2
.SelectMany(dropList => dropList)
.Any(drop => drop == item))
.ToList())
.ToList();
For instance
List<List<int>> list1 = new List<List<int>>() {
new List<int>() { 1, 2, 2, 3, 3, 4, 4},
new List<int>() { 2,},
new List<int>() { 5, 6,}
};
// We should remove 2, 5, 3 whenever they appear in list1
List<List<int>> list2 = new List<List<int>>() {
new List<int>() { 2, 5},
new List<int>() { 3, 3},
};
var result = list1
.Select(list => list
.Where(item => !list2
.SelectMany(dropList => dropList)
.Any(drop => drop == item))
.ToList())
.ToList();
string report = string.Join(Environment.NewLine, result
.Select(line => $"[{string.Join(", ", line)}]"));
Console.Write(report);
Outcome:
[1, 4, 4]
[]
[6]
Not sure if you wanted to remove list1 lists where there is no longer anything in it. Also wasn't sure if you wanted to check that every item in a sublist matches all of a sublist of list2.
var list1 = new List<List<int>>();
var list2 = new List<List<int>>();
var flatList2 = list2.SelectMany(l2 => l2).Distinct();
var result = list1
.Select(o => o
.Where(inner => !flatList2.Contains(inner)))
.Where(o => o.Any());
The below one is exactly the same, it just has different variable names. I think it might help people understand a little more. As we are dealing with a two dimensional array, I always find it a little easier to think of it like a table.
var table = new List<List<int>>();
var table2 = new List<List<int>>();
var distinctColumns = table2.SelectMany(row => row).Distinct();
var result = table
.Select(row => row
.Where(column => !distinctColumns.Contains(column)))
.Where(row => row.Any());
I have two list of string.
var list1 = new List<string> { "1", "12", "21", "34", "22" };
var list2 = new List<string> { "1", "2" };
I Need select items of list1 where item StartsWith by items in list2 : "1", "12", "21", "22"
//foreach solution : "1", "12", "21", "22"
var result1 = new List<string>();
foreach (var item in list2)
result1.AddRange(list1.Where(x => x.StartsWith(item)).ToList());
//linq solution : "1"
var result2 = list1.Where(x => list2.Contains(x)).ToList();
How can I get result1 by linq solution?
You can use a combination of Where with Any like:
var query = list1.Where(s1 => list2.Any(s2 => s1.StartsWith(s2))).ToList();
and you will end up with:
{"1","12","21","22"}
another option is doing the cross join and then query like:
var query = from s1 in list1
from s2 in list2
where s1.StartsWith(s2)
select s1;
var result = list1.Where(x => list2.Any(y => x.StartsWith(y)).ToList();
Using NinjaNye.SearchExtensions you can do something like the following
using NinjaNye.SearchExtensions;
var query = list.Search(x => x).StartsWith(list2);
I have LIST1 <> and LIST2 <> and like to compare these two lists. Followings are my conditions..
1-If LIST1 and LIST2 have the same items than add same items to LIST3
2-If LIST1 doesnt contain LIST2 items than add different items to LIST4
3-if LIST2 doesnt contain LIST1 items than add different items to LIST5
lets say my result is like below depends on the conditions;
LIST1<string> = A,B,C,D
LIST2<string> = A,K,F,C
LIST3<string> = A,C
LIST4<string> = B,D
LIST5<string> = K,F
here is my code;
foreach (string src in LIST1)
{
foreach (string trg in LIST2)
{
if (LIST1.ToString() == LIST2.ToString())
{
LIST3.Add(LIST1.ToString());
}
else
{
LIST4.Clear();
foreach (string l3 in LIST1)
{
if (!LIST2.Contains(l3))
LIST4.Add(l3);
}
LIST5.Clear();
foreach (string l4 in LIST2)
{
if (!LIST1.Contains(l4))
{
LIST5.Add(l4);
}
}
}
}
}
A quick way to do this would be:
var list3 = list1.Intersect(list2).ToList();
var list4 = list1.Except(list2).ToList();
var list5 = list2.Except(list1).ToList();
Update: If you have to do with larger lists (and/or have to write this in multiple places), you can write an extension method like below:
public static Tuple<IEnumerable<T>, IEnumerable<T>, IEnumerable<T>> Diff<T>(
this IEnumerable<T> first, IEnumerable<T> second)
{
var intersection = new List<T>();
var onlyInFirst = new HashSet<T>();
var onlyInSecond = new HashSet<T>(second);
foreach (var item in first)
{
if (onlyInSecond.Remove(item)) intersection.Add(item);
else onlyInFirst.Add(item);
}
return Tuple.Create<IEnumerable<T>, IEnumerable<T>, IEnumerable<T>>
(intersection, onlyInFirst, onlyInSecond);
}
This method returns a tuple of three IEnumerable<T>s representing the set of intersection, set of items only in the first collection, and set of items only in the second collection; respectively.
Usage:
var list1 = new[] { "A", "B", "C", "D" };
var list2 = new[] { "A", "K", "F", "C" };
var diff = list1.Diff(list2);
// diff.Item1 = A,C (intersection)
// diff.Item2 = B,D (only in first)
// diff.Item3 = K,F (only in second)
Not sure what this has to do with sorting, but here's Linq statements for each condition:
List3 = List1.Intersect(List2).ToList();
List4 = List1.Where(l1 => !List2.Any(l2 => l2 == l1)).ToList();
List5 = List2.Where(l2 => !List1.Any(l1 => l2 == l1)).ToList();
as pointed out in comments Except will work too:
List4 = List1.Except(List2).ToList();
List5 = List2.Except(List1).ToList();
There are two lists:
List<string> excluded = new List<string>() { ".pdf", ".jpg" };
List<string> dataset = new List<string>() {"valid string", "invalid string.pdf", "invalid string2.jpg","valid string 2.xml" };
How can I filter-out values from the "dataset" list which contain any keyword from the "excluded" list?
var results = dataset.Where(i => !excluded.Any(e => i.Contains(e)));
// Contains four values.
int[] values1 = { 1, 2, 3, 4 };
// Contains three values (1 and 2 also found in values1).
int[] values2 = { 1, 2, 5 };
// Remove all values2 from values1.
var result = values1.Except(values2);
https://www.dotnetperls.com/except
Try:
var result = from s in dataset
from e in excluded
where !s.Contains(e)
select e;
var result=dataset.Where(x=>!excluded.Exists(y=>x.Contains(y)));
This also works when excluded list is empty.
var result = dataset.Where(x => !excluded.Contains(x));