2012-11-28 122 views
0

我有以下字典:在字典的键中删除重复

Dictionary<string, string> test = new Dictionary<string, string>(); 
test.Add("1|1", "blue"); 
test.Add("1|2", "Nice"); 
test.Add("1|3", "Jaish"); 
test.Add("2|2", "Muna"); 
test.Add("3|1", "haha"); 
test.Add("3|2", "green"); 
test.Add("4|1", "red"); 
Dictionary<string, string> test2 = new Dictionary<string, string>(); 
foreach (KeyValuePair<string, string> entry in test) 
{ 
    if (!test2.ContainsValue(entry.Key)) 
     test2.Add(entry.Key, entry.Key); 
} 

我想删除下面的重复值:

test.Add("1|2", "Nice"); 
test.Add("1|3", "Jaish"); 
test.Add("3|2", "green") 

因此,移除重复的Dictionary的密钥计数后应4.

+7

它们不是重复的。你不能在字典中有重复的键 – Habib

+0

我知道字典键不包含重复项,但我想要唯一的字典键数。 – KCS

+0

你对*重复*的定义是什么? '1 | 2','1 | 3'和'3 | 2'是三个不同的值,因此它们不是重复的。 –

回答

5

假设通过管道拆分字符串的第一部分定义了重复项:

var uniques = test.GroupBy(kv => kv.Key.Split('|')[0]) 
        .Select(g => g.First()) 
        .ToDictionary(kv => kv.Key, kv => kv.Value); 

这总是选择每个组的第一个键值对。

+1

+1来澄清问题,但蒂姆,你能确定它总是选择'1 | 1'对'First()',我认为顺序不能得到保证。 – Habib

+0

谢谢蒂姆你的代码对我来说是完美的解决方案。 – KCS

+0

@Habib:订单对于OP来说并不重要,至少他没有提到它。所以,首先要把'首先'理解为_whatever_。如果有需要排序的东西,他需要'First'之前的'OrderBy'或者使用[predicate重载](http://msdn.microsoft.com/en-us/library/bb535050.aspx)。 –

0

假设你的例子是人为的,你不想使用那些管道分隔键...

要做到这一点最简单的方法是不使用Dictionary.Add(..),而是刚才设置的值

test["1"] = "blue"; 
test["1"] = "NICE"; 
test["1"] = "Jaish"; 

Debug.Assert(test.Count == 1); 

但是,你必须决定,如果这是你想要的逻辑,它只是覆盖每次

1

实施IEqualityComparer<string>这将不会允许您插入重复的项目

var test = new Dictionary<string, string>(new MyStringEqualityComparer()); 

...

public class MyStringEqualityComparer : IEqualityComparer<string> 
{ 
    public bool Equals(string x, string y) 
    { 
     return x.Split('|')[0] == y.Split('|')[0]; 
    } 

    public int GetHashCode(string obj) 
    { 
     return obj.Split('|')[0].GetHashCode(); 
    } 
} 
+0

感谢分享你的想法,但我需要这种类型的字典。 – KCS

0

我认为在你输入的键|符号应该被解释为“或”。如果是这样的话,你可以先打出键产生新的键值对每个关键部分:

var test2 = test.SelectMany(kvp => 
    kvp.Key.Split('|').Select(k => 
     new KeyValuePair<string, string>(k, kvp.Value))); 

...然后取适量的第一个值对每个新的关键:

var test3 = test2.GroupBy(kvp => kvp.Key) 
       .Select(g => g.First()) 
       .ToDictionary(kvp => kvp.Key, kvp => kvp.Value); 
0

如果|意味着或然后你可以产生这样一个新的独特的字典。

var oredDict = new Dictionary<int, string>(); 
foreach (var kv in test.ToArray()) 
{ 
    var keys = kv.Key.Split('|').Select(int.Parse); 
    oredDict[keys.First() | keys.Last()] = kv.Value; 
}