如果我有两个通用列表,List,我想根据Place.Id属性将所有唯一的Place对象合并到一个List中,有效的方法是什么?
一个列表将始终包含50个,另一个列表可能包含更多。
答案 0 :(得分:2)
result = list1.Union(list2, new ElementComparer());
您需要创建ElementComparer来实现IEqualityComparer。例如。见this
答案 1 :(得分:1)
注意:.NET 3.5&上方。
答案 2 :(得分: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)
}
答案 3 :(得分: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的交集中。
答案 4 :(得分:0)
如果您需要速度,则需要使用哈希机制进行比较。我要做的是维护你已经读过的id的哈希集,然后在尚未读取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个元素而另一个列表有更多元素的事实没有任何含义。除非您知道列表已订购......