简体   繁体   中英

Extracting unique keys from key/value pairs, and grouping the values in an array

Let's say I have a List<NameValuePair> , where NameValuePair is a simple object that has a Name property and a Value property, both strings.

The list is populated with values like this:

name = "name1", value = "value1"
name = "name1", value = "value2"
name = "name2", value = "value3"
name = "name3", value = "value4"

Note that there are two instances of the "name1" key. There can be any number of keys (since this is a List).

I want to turn this List into a new list, which has just unique keys, and groups any values with the same key name as an array/list of that key.

So the above should become:

name = "name1", value = "value1", "value2" // value is a string array or list
name = "name2", value = "value3"
name = "name3", value = "value4"

What is the easiest way to accomplish this?

The easiest way is with a ILookup , which is essentially like a dictionary but can have more than one value for each key.

You can do something like this to create your lookup:

var lookup = list.ToLookup(pair => pair.name, 
                           pair => pair.value);

Then you could print the name/value pairs like this:

foreach (var nameGroup in lookup)
{
    var name = nameGroup.Key;
    foreach (string value in nameGroup)
        Console.WriteLine("Name: {0}, Value: {1}", name, value);
}

Maybe with a Dictionary<string,List<string>> you could do something like


for (var kv in mylistofnamed) {
   if (!dict.ContainsKey(kv.Key))
      dict[kv.Key] = new List<string>();
   dict[kv.Key].Add(kv.Value);
}
?

If you only need a read-only collection then Lookup will do the trick, as in Meta-Knight's answer .

If you need to modify the collection after its initial creation/population, then you probably need something like Dictionary<string, List<string>> . You can create and populate such a dictionary from your original list using LINQ:

var dict = list
    .GroupBy(x => x.Name)
    .ToDictionary(x => x.Key, y => y.Select(z => z.Value).ToList()); 

One way is with a dictionary:

http://arcanecode.com/2007/03/05/dictionaries-in-c-the-hashtable/

A HashTable can do what you need with unique keys. You will have to supply a List as the value however, since you will be storing multiple values per key.

Here's another easy example:

http://dotnetperls.com/hashtable-keys

You will need to iterate over each KeyValuePair in your list to populate the HashTable by storing the name as the key and the values as the value. Because you may have a name that points to multiple values, you will need your values in the HashTable to be Lists.

Check for the existence of the name in the HashTable, if it's not there, create a new list for that name and add the value to the list. If the key already exists, access that element in the HashTable and add the new value to the list that maps to the key.

All classes that implement the IDictionary interface or the Generic IDictionary Interface enforce uniqueness checks for the Keys. You could use any of the classes, though I confess my preference for the Generic Dictionary<TKey, TValue> class.

When adding values, you can just check if the Dictionary object already contains the supplied Key. If not, then you can add the item into the Dictionary.

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