C# filter list with LINQ Where. The next example filters a list with LINQ's Where method. var vals = new List<int> {-1, -3, 0, 1, 3, 2, 9, -4}; List<int> filtered = vals. Where(x => x > 0).
Select will always return the same number of elements in the list (regardless of a filter condition you may have). Where can return less elements depending on your filter condition.
Have a look at the Except method, which you use like this:
var resultingList =
listOfOriginalItems.Except(listOfItemsToLeaveOut, equalityComparer)
You'll want to use the overload I've linked to, which lets you specify a custom IEqualityComparer. That way you can specify how items match based on your composite key. (If you've already overridden Equals, though, you shouldn't need the IEqualityComparer.)
Edit: Since it appears you're using two different types of classes, here's another way that might be simpler. Assuming a List<Person>
called persons
and a List<Exclusion>
called exclusions
:
var exclusionKeys =
exclusions.Select(x => x.compositeKey);
var resultingPersons =
persons.Where(x => !exclusionKeys.Contains(x.compositeKey));
In other words: Select from exclusions just the keys, then pick from persons all the Person objects that don't have any of those keys.
I would just use the FindAll method on the List class. i.e.:
List<Person> filteredResults =
people.FindAll(p => return !exclusions.Contains(p));
Not sure if the syntax will exactly match your objects, but I think you can see where I'm going with this.
Many thanks for this guys.
I mangaged to get this down to one line:
var results = from p in People
where !(from e in exclusions
select e.CompositeKey).Contains(p.CompositeKey)
select p;
Thanks again everyone.
var thisList = new List<string>{ "a", "b", "c" };
var otherList = new List<string> {"a", "b"};
var theOnesThatDontMatch = thisList
.Where(item=> otherList.All(otherItem=> item != otherItem))
.ToList();
var theOnesThatDoMatch = thisList
.Where(item=> otherList.Any(otherItem=> item == otherItem))
.ToList();
Console.WriteLine("don't match: {0}", string.Join(",", theOnesThatDontMatch));
Console.WriteLine("do match: {0}", string.Join(",", theOnesThatDoMatch));
//Output:
//don't match: c
//do match: a,b
Adapt the list types and lambdas accordingly, and you can filter out anything.
https://dotnetfiddle.net/6bMCvN
You can use the "Except" extension method (see http://msdn.microsoft.com/en-us/library/bb337804.aspx)
In your code
var difference = people.Except(exclusions);
I couldn't figure out how to do this in pure MS LINQ, so I wrote my own extension method to do it:
public static bool In<T>(this T objToCheck, params T[] values)
{
if (values == null || values.Length == 0)
{
return false; //early out
}
else
{
foreach (T t in values)
{
if (t.Equals(objToCheck))
return true; //RETURN found!
}
return false; //nothing found
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With