【发布时间】:2017-10-30 05:02:14
【问题描述】:
我有一个包含 20 个项目的元素列表和一个包含 5 个项目的数组,我需要比较每个项目的公共属性,如果它匹配..我需要将它们过滤到 o/p 列表中。我如何有效地比较它们,而不进行 20 * 5 = 100 次比较。可能是通过使用哈希图?请帮忙...谢谢
【问题讨论】:
标签: c# arrays performance list hashmap
我有一个包含 20 个项目的元素列表和一个包含 5 个项目的数组,我需要比较每个项目的公共属性,如果它匹配..我需要将它们过滤到 o/p 列表中。我如何有效地比较它们,而不进行 20 * 5 = 100 次比较。可能是通过使用哈希图?请帮忙...谢谢
【问题讨论】:
标签: c# arrays performance list hashmap
使用 LINQ-to-objects 扩展方法Enumerable.Join 可能是最简洁的表达方式:
List<MyListType> matches = myList
.Join(myArray,
myListItem => myListItem.someProperty, //if this prop
myArrayItem => myArrayItem.someProperty, //and this prop match
(myListItem, myArrayItem) => myListItem) //project to...
.ToList();
在内部,它使用从连接的左侧(上面的myList)创建的类似哈希表的结构,然后迭代连接的右侧(上面的myArray)在集合中寻找匹配项从左侧创建。
与您上面描述的(简单)笛卡尔积相比,这显着加快了处理速度(“20 * 5 = 100 次比较”)
实际上,它做了这样的事情:
var lookup = lhs.ToLookup(leftItem => leftItem.someProp);
var matches = rhs.SelectMany(rightItem =>
lookup[rightItem.someProp]
.Select(leftItem => MethodToBeCalledWithTwoMatchingItems(leftItem, rightItem)));
【讨论】:
只散列较小的列表或更改较少的列表更有效:
var hashSet = new HashSet<int> { 1, 2, 3, 4, 5 };
var result = list1.Where(item => hashSet.Contains(item.Property));
【讨论】: