C#:从字典中删除重复值?

时间:2009-09-22 19:27:03

标签: c# linq .net-3.5 dictionary

如何创建字典中没有重复值的字典,该字典可能具有重复值?

IDictionary<string, string> myDict = new Dictionary<string, string>();

myDict.Add("1", "blue");
myDict.Add("2", "blue");
myDict.Add("3", "red");
myDict.Add("4", "green");


uniqueValueDict = myDict.???

修改

- 我不关心保留哪个键。 - 是否有使用Distinct()操作的东西?

8 个答案:

答案 0 :(得分:48)

你想对重复做什么?如果您不介意丢失哪个密钥,只需构建另一个字典:

IDictionary<string, string> myDict = new Dictionary<string, string>();

myDict.Add("1", "blue");
myDict.Add("2", "blue");
myDict.Add("3", "red");
myDict.Add("4", "green");

HashSet<string> knownValues = new HashSet<string>();
Dictionary<string, string> uniqueValues = new Dictionary<string, string>();

foreach (var pair in myDict)
{
    if (knownValues.Add(pair.Value))
    {
        uniqueValues.Add(pair.Key, pair.Value);
    }
}

假设您正在使用.NET 3.5。如果您需要.NET 2.0解决方案,请告诉我。

这是一个基于LINQ的解决方案,我发现它非常紧凑......

var uniqueValues = myDict.GroupBy(pair => pair.Value)
                         .Select(group => group.First())
                         .ToDictionary(pair => pair.Key, pair => pair.Value);

答案 1 :(得分:7)

蛮力解决方案将类似于以下

var result = dictionary
    .GroupBy(kvp => kvp.Value)
    .ToDictionary(grp => grp.First().Value, grp.Key)

假设您并不真正关心用于表示一组重复项的密钥,并且可以重建字典。

答案 2 :(得分:3)

Jon打败了我的.NET 3.5解决方案,但如果您需要.NET 2.0解决方案,这应该可以使用:

        List<string> vals = new List<string>();
        Dictionary<string, string> newDict = new Dictionary<string, string>();
        foreach (KeyValuePair<string, string> item in myDict)
        {
            if (!vals.Contains(item.Value))
            {
                newDict.Add(item.Key, item.Value);
                vals.Add(item.Value);
            }
        }

答案 3 :(得分:1)

foreach (var key in mydict.Keys)
  tempdict[mydict[key]] = key;
foreach (var value in tempdict.Keys)
  uniquedict[tempdict[value]] = value;

答案 4 :(得分:1)

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

答案 5 :(得分:1)

我就这样做了:

                dictionary.add(control, "string1");
                dictionary.add(control, "string1");
                dictionary.add(control, "string2");
              int x = 0;
        for (int i = 0; i < dictionary.Count; i++)
        {         
            if (dictionary.ElementAt(i).Value == valu)
            {
                x++;
            }
            if (x > 1)
            {
                dictionary.Remove(control);
            }
        }

答案 6 :(得分:0)

除了Jon Skeet的答案,如果您的值是实习生对象,您可以使用:

var uniqueValues = myDict.GroupBy(pair => pair.Value.Property)
                     .Select(group => group.First())
                     .ToDictionary(pair => pair.Key, pair => pair.Value);

这样您只会在对象的一个​​属性上删除副本

答案 7 :(得分:0)

对于那些使用Revit API的人来说,这是一个可以帮我删除重复元素的方法,当你不能使用say wallType作为你的对象类型而需要利用原始元素时。这是一个漂亮的伴侣。

  //Add Pair.value to known values HashSet
                 HashSet<string> knownValues = new HashSet<string>();

                Dictionary<Wall, string> uniqueValues = new Dictionary<Wall, string>();

                 foreach (var pair in wall_Dict)
                 {
                     if (knownValues.Add(pair.Value))
                     {
                         uniqueValues.Add(pair.Key, pair.Value);
                     }
                 }