2016-01-08 45 views
1

我有一个带有string键和List<string>值的字典。我想为每个列表获取唯一的值。从字典中删除重复值<string,List <string>> with LINQ

例如,该输入数据:

{ 
    "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从给定的输入中获取此输出?

回答

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

,你的代码没有工作,因为它是寻找独特名单相比,内唯一值那些列表。因为每个列表在内存中都是不同的地方(你知道这是因为修改一个不会修改另一个),因此调用所产生的每个组只有一个元素长。


原来的问题是更清楚比现在,所以我包括几个变化,以确保正确的答案被发现。下面列出了后人的名字,但他们证明不适用这种特殊情况。


和公正的好办法,你said you need to“摆脱重复值的”,这是不明确的。如果你想扔掉任何有任何重复,

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

你读心术? :D – dotctor

+0

@dotctor不,但我确实在互联网上玩过一个。 –

+0

@Matthew - 非常感谢 - 阅读我的想法(我的错误是问这样一个模糊的问题),谢谢你回答我的第一个问题在这个网站上.. :) – sst

相关问题