我们说我有IEnumerable
个键/值对,其中包含重复项。如果我在其上调用ToLookup
并传递选择键和值的lambdas,我将以Lookup
结束,其中所有键都是唯一的,但值列表可以包含重复项。有没有什么好的方法可以在一个LINQ查询语句中以Lookup
结束,其中没有值列表包含重复项?
我无法在原始序列上调用Distinct
,因为元素是按值重复但不是按对象标识重复,并且Distinct
不会将lambda用于选择器我可以使用。
答案 0 :(得分:1)
在构建Lookup与select select之前,您可以使用GroupBy。然而,这并不是那么好:
这样的事情:
sequence.GroupBy(kvp => _getKey(kvp))
.SelectMany(grp => grp.Distinct()
.Select(value => new { grp.Key, Value = value}))
.ToLookUp(grp => grp.Key, grp=> grp.Value);
替代方案是使用字典,因为我不太确定你为什么要使用查找。
sequence.GroupBy(kvp => _getKey(kvp))
.Select(g => new { g.Key, Values = new HashSet<WhatEver>(g)})
.ToDictionary(v => v.Key, v => v.Values);
Hashset的替代方案是提供带有Distinct()
的EqualityComparer public sealed class WhatEverComparer : IEqualityComparer<WhatEver>
{
... implement interface..
}
然后
sequence.GroupBy(kvp => _getKey(kvp))
.Select(g => new { g.Key, Values = g.Distinct(new WhatEvercomparer()).ToArray()})
.ToDictionary(v => v.Key, v => v.Values);
答案 1 :(得分:0)
您可以使用一点GroupBy
黑客而不是Distinct
:
var lookup = source.GroupBy(i => get_unique_id(i),
(key, group) => group.First()).ToLookup(i => i.Key, i => i.Value);
GroupBy
将根据您选择的“唯一值”创建群组。对group.First
的调用只会保留该组的一个元素。因此,您使用相同的“唯一值”或“组标准”删除所有其他人。这基本上是一个扩展的Distinct
。
get_unique_id
应为相同的键/值组合返回相同的值,否则返回不同的值。
答案 2 :(得分:0)
如果你引入一个匿名的中间对象,这似乎就像一个微不足道的练习。
试试这个:
var lookup =
sequence
.Select(x => new { x.Key, x.Value })
.Distinct()
.ToLookup(x => x.Key, x => x.Value);
因为你可以在匿名变量上调用.Distinct()
,所以这应该可以正常工作。