如何产生完全独特的查找?

时间:2015-05-11 22:11:09

标签: .net linq

我们说我有IEnumerable个键/值对,其中包含重复项。如果我在其上调用ToLookup并传递选择键和值的lambdas,我将以Lookup结束,其中所有键都是唯一的,但值列表可以包含重复项。有没有什么好的方法可以在一个LINQ查询语句中以Lookup结束,其中没有值列表包含重复项?

我无法在原始序列上调用Distinct,因为元素是按值重复但不是按对象标识重复,并且Distinct不会将lambda用于选择器我可以使用。

3 个答案:

答案 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(),所以这应该可以正常工作。