0

如果我有两个通用列表 List,并且我想基于 Place.Id 属性将所有唯一的 Place 对象合并到一个 List 中,那么有什么好的方法可以有效地做到这一点?

一个列表将始终包含 50 个,另一个列表可能包含更多。

4

5 回答 5

2
result = list1.Union(list2, new ElementComparer());

您需要创建 ElementComparer 来实现 IEqualityComparer。例如看到这个

于 2012-06-26T04:03:14.313 回答
1

Enumerable.Distinct 方法

注意:.NET 3.5 及更高版本。

于 2012-06-26T03:58:27.293 回答
1

如果你想强调效率,我建议你自己写一个小方法来做合并:

List<Place> constantList;//always contains 50 elements. no duplicate elements
List<Place> targetList;
List<Place> result;

Dictionary<int, Place> dict;
for(var p in constantList)
   dict.Put(p.Id,p);

result.AddRange(constantList);

for(var p in targetList)
{
   if(!dict.Contains(p.Id))
       result.Add(p)       
}
于 2012-06-26T04:26:23.280 回答
1

如果您想避免必须定义自己的 ElementComparer 而只使用 lambda 表达式,可以尝试以下方法:

List<Place> listOne = /* whatever */;
List<Place> listTwo = /* whatever */;
List<Place> listMerge = listOne.Concat(
                           listTwo.Where(p1 => 
                               !listOne.Any(p2 => p1.Id == p2.Id)
                           )
                        ).ToList();

本质上,这只会将 Enumerable listOne 与 listTwo 中的所有元素的集合连接起来,这样这些元素就不会在 listOne 和 listTwo 之间的交集中。

于 2012-06-26T05:04:07.667 回答
0

如果您需要速度,则需要使用散列机制进行比较。我要做的是维护您已经读取的 id 的 Hashset,然后如果尚未读取 id,则将元素添加到结果中。您可以根据需要对任意数量的列表执行此操作,并且如果您想在合并结束之前开始使用,则可以返回 IEnumerable 而不是列表。

 public IEnumerable<Place> Merge(params List<Place>[] lists)
 {
     HashSet<int> _ids = new HashSet<int>();
     foreach(List<Place> list in lists)
     {
         foreach(Place place in list)
         {
             if (!_ids.Contains(place.Id))
             {
                 _ids.Add(place.Id);
                 yield return place;
             }
         }
     }
 }

一个列表有 50 个元素,而另一个列表有更多元素这一事实没有任何含义。除非你知道这些列表是有序的......

于 2012-06-27T16:44:50.643 回答