Linq 获取未在多个列表之间共享的值
编写一个比较 n 个列表并返回所有未出现在所有列表中的值的方法的最有效方法是什么,以便
var lists = new List<List<int>> {
new List<int> { 1, 2, 3, 4 },
new List<int> { 2, 3, 4, 5, 8 },
new List<int> { 2, 3, 4, 5, 9, 9 },
new List<int> { 2, 3, 3, 4, 9, 10 }
};
public IEnumerable<T> GetNonShared(this IEnumerable<IEnumerable<T>> lists)
{
//...fast algorithm here
}
lists.GetNonShared
();
返回 1, 5, 8, 9, 10
我有
public IEnumerable<T> GetNonShared(this IEnumerable<IEnumerable<T>> lists)
{
return list.SelectMany(item => item)
.Except(lists.Aggregate((a, b) => a.Intersect(b));
}
但我不确定这是否有效。顺序并不重要。谢谢!
What's the most efficient way to write a method that will compare n lists and return all the values that do not appear in all lists, so that
var lists = new List<List<int>> {
new List<int> { 1, 2, 3, 4 },
new List<int> { 2, 3, 4, 5, 8 },
new List<int> { 2, 3, 4, 5, 9, 9 },
new List<int> { 2, 3, 3, 4, 9, 10 }
};
public IEnumerable<T> GetNonShared(this IEnumerable<IEnumerable<T>> lists)
{
//...fast algorithm here
}
so that
lists.GetNonShared();
returns 1, 5, 8, 9, 10
I had
public IEnumerable<T> GetNonShared(this IEnumerable<IEnumerable<T>> lists)
{
return list.SelectMany(item => item)
.Except(lists.Aggregate((a, b) => a.Intersect(b));
}
But I wasn't sure if that was efficient. Order does not matter. Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
编辑:我想我会这样想......
你想要所有列表的并集,减去所有列表的交集。这实际上就是您原来的做法,尽管获得了重复的输入,但还是让
Except
执行Union
的“设置”操作。在这种情况下,我怀疑只需构建两个HashSet
并就地完成所有工作即可更有效地完成此操作:请注意,这现在是急切的,没有推迟。
这是一个替代选项:
如果列表可能多次包含相同的项目,那么您需要在其中进行不同的调用:
编辑:现在我已经更正了这一点,我理解您的原始代码...并且我怀疑我可以找到更好的东西...思考...
EDIT: I think I'd think of it like this...
You want the union of all the lists, minus the intersection of all the lists. That's effectively what your original does, leaving
Except
to do the "set" operation ofUnion
despite getting duplicate inputs. In this case I suspect you could do this more efficiently just building up twoHashSet
s and doing all the work in-place:Note that this is now eager, not deferred.
Here's an alternative option:
If it's possible for a list to contain the same item more than once, you'd want a Distinct call in there:
EDIT: Now I've corrected this, I understand your original code... and I suspect I can find something better... thinking...
我认为您需要创建一个中间步骤,即查找所有列表共有的所有项目。使用集合逻辑很容易做到这一点 - 它只是第一个列表中的项目集与每个后续列表中的项目集相交。不过,我认为这一步在 LINQ 中不可行。
I think you need to create an intermediate step, which is finding all the items which are common to all lists. This is easy to do with set logic - it's just the set of items in the first list intersected with the set of items in each succeeding list. I don't think that step's doable in LINQ, though.
//对于 .net >= 4.5 使用 HashSet 和 SymmetricExceptWith
//use HashSet and SymmetricExceptWith for .net >= 4.5