从字典中删除重复的值<;字符串,列表<;字符串>>;使用LINQ

本文关键字:字符串 lt gt LINQ 使用 列表 删除 字典 | 更新日期: 2023-09-27 18:29:36

我有一个字典,里面有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);

这似乎没有返回我预期的结果,而是返回了我原来词典的副本。这是一个DotNetFiddle,说明我的代码无法工作。

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

从字典中删除重复的值<;字符串,列表<;字符串>>;使用LINQ

我想你需要这样的东西:

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调用产生的每个组只有一个元素长。


最初的问题远没有现在清楚,所以我加入了几个变体,以确保找到正确的答案。下面列出了这些内容,以供后人参考,但事实证明它们并不适用于这种特殊情况


为了更好地衡量,你说你需要"消除重复的值",这是模棱两可的。如果你想扔掉任何有重复的东西,

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"]
}