-1

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.

arpaqua
  • 3
  • 3
  • Can you share your code with us? –  Mar 15 '21 at 14:38
  • so actually the `vals` are indexes of `keys` elements and can be removed. You want to group by value and get the indexes of grouped elements. – Jacek Mar 15 '21 at 14:39
  • Does this answer your question? [can I sort a list based on another list in C#](https://stackoverflow.com/questions/66569013/can-i-sort-a-list-based-on-another-list-in-c-sharp) – Neil Mar 15 '21 at 14:48
  • [Zip](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.zip?view=net-5.0) those 2 collection into one `List` with `class CustomObject{ string Key{get;set;} int Value{get;set;} }`. Then use a simple `GroupBy` – Self Mar 15 '21 at 14:55
  • Amy, the code is complex, I'm working with a specific technical SW (Revit). I simplified my "issue". Jacek, vals are the elements I want to group. Self, I don't want create another class for this temp task of grouping. After grouping, the list of keys will be abandoned. – arpaqua Mar 15 '21 at 15:10

3 Answers3

1

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();
Jacek
  • 829
  • 12
  • 31
  • It's just what I was looking for. Thank you so much. I know that for you LINQ is easy, but I'm a noob about it. – arpaqua Mar 15 '21 at 15:41
1

You can try Zip in order to establish key / value correspondence (n-th key corresponds to n-th value), i.e.

"a" corresponds to 0
"a" corresponds to 1
"b" corresponds to 2
...
"b" corresponds to 7

and then put GroupBy where we group by key, but select value:

using System.Linq;

...

var result = keys
  .Zip(vals, (k, v) => new {k, v})
  .GroupBy(pair => pair.k, pair => pair.v)
  .Select(group => group.ToList())
  .ToList();
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
0

There are multiple classes such as Tuple or Dictionary that can do this. Also DataTable. This is an example of Dictionary

    Dictionary<string, int[]> group = new Dictionary<string, int[]>();
        group.Add("a", new int []{0,1,3,6 });
        group.Add("b", new int[] { 2, 7 });
        group.Add("c", new int[] { 4, 5 });

Find your group by Key like this

    var intArray = group.Where(x => x.Key == "a");
  • _Find your group by Key like this_ `group.Where(x => x.Key == "a");` ?? Chotto matte kudasai... `group["A"]` Thats how you access a value.. Where will give an IEnumerable make no sense. My heart skipped a beat, reading this. . For reference So question [How to get dictionary value by key?](https://stackoverflow.com/questions/12169443/) – Self Mar 15 '21 at 15:10
  • Fair enough, you added it.. your heart can rest now. – Wanderer11 Mar 15 '21 at 15:44