Заполнить новый словарь из старого словаря - PullRequest
2 голосов
/ 03 февраля 2020

У меня есть Dictionary<string, int>, где строка - это рандомизированная коллекция символов, а int - это сумма ASCII этой строки.

например,

    ["aaaaaaaaab", 971],
    ["aaaaaaaaba", 971],
    ["aaaaaaabaa", 971],
    ["aaaaaabaaa", 971]

Я хотел бы создать новый словарь из оригинала, где новый ключ - это значение оригинала, а новое значение - List<string>, которое будет содержать все строки с ключом в виде суммы ASCII.

например

    [971, List<string>{ "aaaaaaaaab", "aaaaaaaaba", "aaaaaaabaa", "aaaaaabaaa"}]

Как мне этого добиться? Я не могу обернуть голову вокруг необходимых шагов.

Ответы [ 4 ]

2 голосов
/ 03 февраля 2020

Использование может GroupBy и ToDictionary

Посылка:

  1. сгруппировать по старый Value
  2. проект в новый словарь с учетом значений GroupBy
    • , которые будут сгруппированный список KeyValuePair из исходного словаря, который, в свою очередь, выбрал из него key (.Select(y => y.Key)

Пример

var newDict = old.GroupBy(x => x.Value)
                 .ToDictionary(x => x.Key, x => x.Select(y => y.Key)
                                                 .ToList());

Дополнительные ресурсы

Метод Enumerable.GroupBy

Группы элементы последовательности.

Метод Enumerable.ToDictionary

Создает Dictionary<TKey,TValue> из IEnumerable<T>.

1 голос
/ 03 февраля 2020

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

var inverse = original
    .GroupBy(p => p.Value)
    .ToDictionary(g => g.Key, g => g.Select(p => p.Key).ToList());
0 голосов
/ 03 февраля 2020

Вот полный пример для любого, кто хочет «обернуть голову», как это сделать, без LINQ.

using System;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        Dictionary<string,int> origDict = new Dictionary<string,int>{{"tttt",1},{"fttt",1},{"fftt",2}};

        var vals = new int[origDict.Count];
        origDict.Values.CopyTo(vals,0);

        var keys = new string[origDict.Count];
        origDict.Keys.CopyTo(keys,0);

        Dictionary<int,List<string>> newDict = new Dictionary<int,List<string>>();
        for(int i = 0; i < vals.Length; i++){
            int val = vals[i];
            if(newDict.ContainsKey(val)){
                newDict[val].Add(keys[i]);
            }else{
                newDict[val] = new List<string>();
                newDict[val].Add(keys[i]);
            }
        }
        foreach(var key in newDict.Keys){
            Console.WriteLine(key);
            foreach(var val in newDict[key]){
                Console.WriteLine(val);
            }
        }
    }
}

Вывод:

1
tttt
fttt
2
fftt
0 голосов
/ 03 февраля 2020

Если вы хотите сделать это без Linq, вы можете сделать следующее:

foreach(KeyValuePair<string, int> entry in dict) {
    if(!dict2.ContainsKey(entry.Value)) {
        dict2[entry.Value] = new List<string>();
    }
    dict2[entry.Value].Add(entry.Key);
}

Предполагая, что dict определен как Dictionary<string, int> dict, а dict2 определен как Dictionary<int, List<string>> dict2

...