这可能看起来很愚蠢,但我发现Except在linq中使用的所有示例都使用两个列表或仅包含字符串或整数的数组,并根据匹配过滤它们,例如:
var excludes = users.Except(matches);
Run Code Online (Sandbox Code Playgroud)
我想使用exclude来保持我的代码简短,但似乎无法找到如何执行以下操作:
class AppMeta
{
public int Id { get; set; }
}
var excludedAppIds = new List<int> {2, 3, 5, 6};
var unfilteredApps = new List<AppMeta>
{
new AppMeta {Id = 1},
new AppMeta {Id = 2},
new AppMeta {Id = 3},
new AppMeta {Id = 4},
new AppMeta {Id = 5}
}
Run Code Online (Sandbox Code Playgroud)
如何获取AppMeta过滤器列表excludedAppIds?
Col*_*inE 67
尝试一个简单的查询位置
var filtered = unfilteredApps.Where(i => !excludedAppIds.Contains(i.Id));
Run Code Online (Sandbox Code Playgroud)
except方法使用相等,您的列表包含不同类型的对象,因此它们包含的任何项都不相同!
dot*_*NET 13
ColinE的答案简单而优雅.如果您的列表较大并且排除了排除的应用列表,则BinarySearch<T>可能会比以前更快Contains.
例:
unfilteredApps.Where(i => excludedAppIds.BinarySearch(i.Id) < 0);
Run Code Online (Sandbox Code Playgroud)
Sco*_*ott 13
我使用Except的扩展方法,允许你将苹果与橘子进行比较,只要它们都有一些可以用来比较它们的常用方法,比如Id或Key.
public static class ExtensionMethods
{
public static IEnumerable<TA> Except<TA, TB, TK>(
this IEnumerable<TA> a,
IEnumerable<TB> b,
Func<TA, TK> selectKeyA,
Func<TB, TK> selectKeyB,
IEqualityComparer<TK> comparer = null)
{
return a.Where(aItem => !b.Select(bItem => selectKeyB(bItem)).Contains(selectKeyA(aItem), comparer));
}
}
Run Code Online (Sandbox Code Playgroud)
然后使用这样的东西:
var filteredApps = unfilteredApps.Except(excludedAppIds, a => a.Id, b => b);
Run Code Online (Sandbox Code Playgroud)
扩展与ColinE的答案非常相似,它只是打包成一个整齐的扩展,可以重复使用,而不需要太多的精神开销.
azu*_*eca 11
这就是LINQ所需要的
public static IEnumerable<T> Except<T, TKey>(this IEnumerable<T> items, IEnumerable<T> other, Func<T, TKey> getKey)
{
return from item in items
join otherItem in other on getKey(item)
equals getKey(otherItem) into tempItems
from temp in tempItems.DefaultIfEmpty()
where ReferenceEquals(null, temp) || temp.Equals(default(T))
select item;
}
Run Code Online (Sandbox Code Playgroud)
List<AppMeta>从排除的List 构造a 并使用Except Linq运算符.
var ex = excludedAppIds.Select(x => new AppMeta{Id = x}).ToList();
var result = ex.Except(unfilteredApps).ToList();
Run Code Online (Sandbox Code Playgroud)
从 .NET 6 开始,现在有一个ExceptBy专门为此设计的内置程序:
var filtered = unfilteredApps.ExceptBy(excludedAppIds, a => a.Id);
Run Code Online (Sandbox Code Playgroud)