User
User

Reputation: 65951

C#: Remove duplicate values from dictionary?

How can I create a dictionary with no duplicate values from a dictionary that may have duplicate values?

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.???

Edit:

-I don't care which key is kept. - Is there something using Distinct() operation?

Upvotes: 22

Views: 36855

Answers (8)

frank jock halliday
frank jock halliday

Reputation: 1

Just a footnote to those using the Revit API, this is one method that works for me in removing duplicate elements, when you can't use say wallType as your object type and instead need to leverage raw elements. it's a beaut mate.

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

Upvotes: 0

MILAD
MILAD

Reputation: 649

This is how I did it:

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

Upvotes: 1

Guillaume V
Guillaume V

Reputation: 1081

In addition to the answer of Jon Skeet , if your value is an intern object you can use :

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

This way you will remove the duplicate only on one property of the object

Upvotes: 0

Daniel Br&#252;ckner
Daniel Br&#252;ckner

Reputation: 59655

The brute-force solution would be something like the following

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

assuming you don't really care about the key used to represent a group of duplicates and it is acceptable to rebuild the dictionary.

Upvotes: 9

Jon Skeet
Jon Skeet

Reputation: 1500635

What do you want to do with the duplicates? If you don't mind which key you lose, just build another dictionary like this:

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

That assumes you're using .NET 3.5, admittedly. Let me know if you need a .NET 2.0 solution.

Here's a LINQ-based solution which I find pleasantly compact...

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

Upvotes: 51

Timothy Carter
Timothy Carter

Reputation: 15785

Jon beat me to the .NET 3.5 solution, but this should work if you need a .NET 2.0 solution:

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

Upvotes: 3

Sivvy
Sivvy

Reputation: 851

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

Upvotes: 1

queen3
queen3

Reputation: 15511

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

Upvotes: 1

Related Questions