删除Dictionary键中的重复项

时间:2012-11-28 09:37:02

标签: c#

我有以下字典:

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。

5 个答案:

答案 0 :(得分:5)

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

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

这始终选择每个组的第一个键值对。

答案 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();
    }
}

答案 2 :(得分:0)

假设您的示例是人为的,并且您不想使用这些以管道分隔的键...

最简单的方法是不使用Dictionary.Add(..),而只是设置值

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

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

但是,您必须确定这是否是您想要的逻辑,它每次都会覆盖

答案 3 :(得分:0)

我认为输入键中的|符号应解释为&#34;或&#34;。如果是这种情况,您可以先拆分密钥,为每个关键部分生成新的键值对:

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);

答案 4 :(得分:0)

如果|表示OR然后您可以生成一个新的唯一字典。

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;
}