C# GROUP a list of values by another list of keys

I’m sure it’s a stupid question, but I cannot find an easy way to group a list by another list. I searched a lot on the internet, but I found only examples with class properties or sorting elements.

I have a string list with keys, for example:

List<string> keys = new List<string>();
keys.Add("a");
keys.Add("a");
keys.Add("b");
keys.Add("a");
keys.Add("c");
keys.Add("c");
keys.Add("a");
keys.Add("b");

and an int list I want to group by the key list, for example:

List<int> vals = new List<int>();
vals.Add(10);
vals.Add(11);
vals.Add(12);
vals.Add(13);
vals.Add(14);
vals.Add(15);
vals.Add(16);
vals.Add(17);

So the result should be a list with sublists like:

{{10,11,13,16},{12,17},{14,15}}

Or maybe also get indices. Thanks in advance.

Answer

Looks like you want to get indexes of elements grouped by value. This is how you’d do it using Linq:

List<string> keys = new List<string>();
keys.Add("a");
keys.Add("a");
keys.Add("b");
keys.Add("a");
keys.Add("c");
keys.Add("c");
keys.Add("a");
keys.Add("b");

var grouped = keys.Select((val, index) => (val, index))
    .GroupBy(x => x.val, x => x.index)
    .ToList();

foreach (var g in grouped)
{
    Console.WriteLine($"{g.Key}: ");
    foreach (var val in g)
    {
        Console.WriteLine($"  {val}");
    }
}

If you really have another list of values which match the order and count of your keys then you can change the code to:

List<string> keys = new List<string>();
keys.Add("a");
keys.Add("a");
keys.Add("b");
keys.Add("a");
keys.Add("c");
keys.Add("c");
keys.Add("a");
keys.Add("b");

List<int> vals = new List<int>();
vals.Add(0);
vals.Add(1);
vals.Add(2);
vals.Add(3);
vals.Add(4);
vals.Add(5);
vals.Add(6);
vals.Add(7);

var grouped = keys.Select((val, index) => (val, index))
    .GroupBy(x => x.val, x => vals[x.index])
    .ToList();

Leave a Reply

Your email address will not be published. Required fields are marked *