Подтвердить что ты не робот

С#: удалить повторяющиеся значения из словаря?

Как создать словарь без дубликатов значений из словаря, который может иметь повторяющиеся значения?

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:

- Мне все равно, какой ключ сохранен. - Есть ли что-то, использующее функцию Distinct()?

4b9b3361

Ответ 1

Что вы хотите делать с дубликатами? Если вы не возражаете против того, какой ключ вы потеряете, просто создайте еще один словарь:

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

Ответ 2

Решение грубой силы будет выглядеть следующим образом

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

предполагая, что вам действительно не нужен ключ, используемый для представления группы дубликатов, и приемлемо пересобирать словарь.

Ответ 3

Джон избил меня до решения .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);
            }
        }

Ответ 4

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

Ответ 5

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

Ответ 6

Вот как я это сделал:

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

Ответ 7

В дополнение к ответу Jon Skeet, если ваше значение является объектом-участником, вы можете использовать:

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

Таким образом вы удалите дубликат только по одному свойству объекта

Ответ 8

Просто примечание для тех, кто использует 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);
                     }
                 }