给定两组值:
var subset = new[] { 2, 4, 6, 8 };
var superset = new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
如何确定 superset
是否包含所有 subset
元素?
我想到了这个方法:
superset.Intersect(subset).Count() == subset.Count()
这是最合乎逻辑和高效的方法吗?
bool contained = !subset.Except(superset).Any();
所以,我的另一个答案很容易使用。但它是O(n*m)的解决方案。
这里有一个稍微不那么友好的O(n+m)解决方案。如果超集非常大,则应使用此解决方案。它避免了反复枚举超集。
HashSet<int> hashSet = new HashSet<int>(superset);
bool contained = subset.All(i => hashSet.Contains(i));
我有一个扩展方法,它使用现有的Contains()方法。我觉得这比使用Instersect()或Except()更直观。
public static bool ContainsAll<T>(this IEnumerable<T> source, IEnumerable<T> values)
{
return values.All(value => source.Contains(value));
}
Except
的 LINQ 实现会迭代源序列一次,存储值(我认为是作为哈希集合),然后迭代目标序列一次,从集合中删除其项。LINQ 高度优化以实现最小迭代。 - Bryan WattsOrderBy
。现在,在这些lambda表达式中执行的操作可能非常低效,但这取决于你自己 :-) 我喜欢你的可读性;我正在考虑添加你的扩展方法与Except
实现,以获得两全其美的效果。 - Bryan Wattspublic static bool ContainsAll<T>(this IEnumerable<T> haystack, IEnumerable<T> needles) { return !needles.Except(haystack).Any(); }
- Felix Alcalafalse
。 - superlogicalsubset.Except(superset).Count() == 0