从字典<string,list <string>&gt;中删除重复值与LINQ

时间:2016-01-08 20:59:04

标签: c# .net linq dictionary

我有一个包含string个密钥和List<string>值的字典。我想为每个列表获取唯一值。

例如,此输入数据:

{
    "first": ["1", "2", "3", "1"],
    "second": ["2", "3", "4", "3"]
}

会回复:

{
    "first": ["1", "2", "3"],
    "second": ["2", "3", "4"]
}

我正在尝试这个,但它没有工作:

var uniq = duplidictionary.GroupBy(x => x.Value)
                          .Select(y => y.First())
                          .ToDictionary( x => x.Key, y => y.Value);

而不是返回我预期的结果,这似乎返回了原始字典的副本。 Here is a DotNetFiddle illustrating my code not working

如何使用LINQ从给定输入中获取此输出?

1 个答案:

答案 0 :(得分:5)

我认为你需要这样的东西:

Dictionary<string, List<string>> dupeLists = ...;

var ret = dupeLists.ToDictionary(c => c.Key, c => c.Value.Distinct().ToList());

这会将项目复制到新词典中,只对值列表中的每个项目进行一次复制。

如果dupeLists看起来像:

{
    "first": ["1", "2", "3", "1"],
    "second": ["2", "3", "4", "3"]
}

然后这将返回:

{
    "first": ["1", "2", "3"],
    "second": ["2", "3", "4"]
}

与这些列表中的唯一值相比,您的代码无法正常工作,因为它找到了唯一的列表。因为每个列表在内存中都是不同的位置(您知道因为修改一个列表并不修改另一个列表),因此GroupBy调用产生的每个组只会是一个元素长。

原始问题远没有现在那么明确,所以我提出了几个变体来确保找到正确的答案。下面列出了后代的内容,但结果却不适用于这种特殊情况。

只是为了好的衡量标准,你said you need to&#34;摆脱重复的价值,&#34;这是模棱两可的。如果你想抛弃任何有重复的东西,

Dictionary<string, List<string>> dupeLists = ...;

var ret = dupeLists.ToDictionary(c => c.Key, c => c.Value.GroupBy(x => x)
                                                         .Where(x => x.Count() == 1)
                                                         .Select(x => x.Key)
                                                         .ToList());

将返回:

{
    "first": ["2", "3"],
    "second": ["2", "4"]
}

既然你在一个失败的日子抓住了我,如果你真的想要返回一份不同项目的平面列表,

Dictionary<string, List<string>> dupeLists = ...;

var ret = dupeLists.SelectMany(c => c.Value).Distinct().ToList();

产生:

["1", "2", "3", "4"]

或者只是在整个字典中只出现一次的那些:

Dictionary<string, List<string>> dupeLists = ...;

var ret = dupeLists
              .SelectMany(c => c.Value)
              .GroupBy(c => c)
              .Where(c => c.Count() == 1)
              .Select(c => c.Key)
              .ToList();

这是:

["4"]

或者只是那些只出现在任何给定列表中的,但没有出现在其他列表中的那些:

Dictionary<string, List<string>> dupeLists = ...;

var ret = dupeLists
              .SelectMany(c => c.Value, (kvp, Value) => new { kvp.Key, Value })
              .GroupBy(c => c.Value)
              .Where(c => c.Select(x => x.Key).Distinct().Count() == 1)
              .GroupBy(c => c.Key, c => c.Value)
              .ToDictionary(c => c.Key, c => c.ToList());

这是,如果我的未经测试的代码仍然存在:

{
    "first": ["1", "1"],
    "second": ["4"]
}