简体   繁体   中英

How to assign one value to multiple keys in a C# dictionary?

I want to define a dictionary of alphabets. In this dictionary, the characters are keys and there are assigned a value for each one. I have written it in the simplest way and as you can see some keys have the same values.

var testDict = 
        new Dictionary <char, int>() { 
            {'A', 1}, {'E', 1}, {'I', 1}, 
            {'O', 1}, {'U', 1}, {'L', 1}, 
            {'N', 1}, {'R', 1}, {'S', 1}, 
            {'T', 1}, 
            {'D', 2}, {'G', 2},
            {'B', 3}, {'C', 3}, {'M', 3}, {'P', 3}, 
            {'F', 4}, {'H', 4}, {'V', 4}, {'W', 4}, {'Y', 4}, 
            {'K', 5}, 
            {'J', 8}, {'X', 8}, 
            {'Q',10}, {'Z',10}};

I need to find the alphabets in it and use the assigned values. How can I write it in a more concise way?

A Dictionary<TKey, TValue> is a collection of keys and values. In this collection, each key is mapped to just one value. And it has been implemented in the System.Collection.Generics namespace.

On the other hand, there is a collection named Lookup<TKey, TElement> which represents a one to many mapping between keys and values. Ie it maps one key to one or more values, and it is in the System.Linq namespace.

You can convert any collections which have implemented the IEnumerable interface and the ToLookup() method in the System.Linq namespace to construct the Lookup<TKey, TElement> collection.

Read more about Lookup collection and Dictionary in the Microsoft tutorials about C# language.

In this question, we could consider a package consisting of two fields, the "Alphabet" character and its "Counts" in a sentence.

class Package
{
    public char Alphabet;
    public int Counts;
}

Then construct the Lookup data structure:

public static void LookupExample()
{
    // Create a dictionary of Packages to put into a Lookup data structure.
    var testDict = new Dictionary <char, int>() { 
         new Package { Alphabet = 'A', Counts = 1},
         new Package { Alphabet = 'B', Counts = 3},
         new Package { Alphabet = 'C', Counts = 3},
         new Package { Alphabet = 'D', Counts = 2},
         new Package { Alphabet = 'E', Counts = 1},
         new Package { Alphabet = 'F', Counts = 4},
         new Package { Alphabet = 'G', Counts = 2},
         new Package { Alphabet = 'H', Counts = 4},
         new Package { Alphabet = 'I', Counts = 1},
         new Package { Alphabet = 'J', Counts = 8},
         new Package { Alphabet = 'K', Counts = 5},
         new Package { Alphabet = 'L', Counts = 1},
         new Package { Alphabet = 'M', Counts = 3},
         new Package { Alphabet = 'N', Counts = 1},
         new Package { Alphabet = 'O', Counts = 1},
         new Package { Alphabet = 'P', Counts = 3},
         new Package { Alphabet = 'Q', Counts = 10},
         new Package { Alphabet = 'R', Counts = 1},
         new Package { Alphabet = 'S', Counts = 1},
         new Package { Alphabet = 'T', Counts = 1},
         new Package { Alphabet = 'U', Counts = 1},
         new Package { Alphabet = 'V', Counts = 4},
         new Package { Alphabet = 'W', Counts = 4},
         new Package { Alphabet = 'X', Counts = 8},
         new Package { Alphabet = 'Y', Counts = 4},
         new Package { Alphabet = 'Z', Counts = 10}};
                                                         

    // Create a Lookup to organize the packages. Use the Counts of each Alphabet as the key value.
    // Select Alpahbet appended to each Counts in the Lookup.
    Lookup<int, char> lookup = (Lookup<int, char>)testDict.ToLookup(p => p.Counts, p => p.Alphabet);

    // Iterate through each IGrouping in the Lookup and output the contents.
    foreach (IGrouping<int, char> packageGroup in lookup)
    {
        // Print the key value of the IGrouping.
        Console.WriteLine(packageGroup.Key);
        // Iterate through each value in the IGrouping and print its value.
        foreach (char chr in packageGroup)
            Console.WriteLine("    {0}", Convert.ToString(chr));
    }
 }

This helps to consider the "Counts" as the new key and assign multiple "Alphabet" characters to it which have same amount for their "Counts" value!

With this extension method:

    public static void Add<TKey, TValue>(this Dictionary<TKey, TValue> dict, TValue value, params TKey[] keys)
    {
        foreach (var key in keys)
            dict.Add(key, value);
    }

You can create a Dictionary like this:

    var testDict =
        new Dictionary<char, int>() {
                {1, 'A', 'E', 'I'},
                {2, 'D', 'G'},
                {3, 'B', 'C', 'M', 'P'},
        };

You can create a dictionary of value to keys. And then, you can use linq to convert it into a dictionary:

var tempDict = new Dictionary<int, List<char>>
{
    {1, new List<char> {'A', 'E','I'}},
    {2, new List<char> {'D','G'}}
};
var finalDict = new Dictionary<char, int>();
tempDict.ForEach(x => x.Value.ForEach(y => finalDict[y] = x.Key));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM