How to convert IEnumerable<IList<T>> to IReadOnlyDictionary<string, IEnumerable<IList<T>>>?

315 Views Asked by At

Let's say I've a class Telemetry as follows:

public class Telemetry
{
   public string Id { get; set; }
   public AdditionalInfo Info { get; set; }
}

Let's say I've a class: TelemetryCollection that implements : IEnumerable<IList<Telemetry>>

I need to group an instance of TelemetryCollection based on Telemetry.Id and get a mapping of Telemetry.Id and TelemetryCollection

How do I get an IDictionary<string, IEnumerable<IList<Telemetry>>> from IEnumerable<IList<Telemetry>>>

1

There are 1 best solutions below

0
Panagiotis Kanavos On BEST ANSWER

Assuming TelemetryCollection contains arrays/lists of Telemetry measurements for the same Id with possible duplicates, you can:

  1. Group the arrays using group by the first array element's Id
  2. Use ToDictionary to collect the grouped arrays into a dictionary
var dict=collection.GroupBy(t=>t[0].Id)
                   .ToDictionary(g=>g.Key,
                                 g=>g.AsEnumerable());

The following example compiles:

//Use a record to save keystrokes
public record Telemetry(string Id ,int Info );

IEnumerable<IList<Telemetry>> collection=new List<IList<Telemetry>>{
            new[]{ new Telemetry("A",1),new Telemetry("A",2)},
            new[]{ new Telemetry("B",1),new Telemetry("B",2)},
            new[]{ new Telemetry("A",3),new Telemetry("A",4)}
        };
var dict=collection.GroupBy(t=>t[0].Id)
                   .ToDictionary(g=>g.Key,g=>g.AsEnumerable());
Console.WriteLine(dict);

And prints:

System.Collections.Generic.Dictionary'2[System.String,System.Collections.Generic.IEnumerable'1[System.Collections.Generic.IList`1[ConsoleApp1.Telemetry]]]

Serializing dict to JSON produces:

{
   "A":[
          [{"Id":"A","Info":1},{"Id":"A","Info":2}], 
          [{"Id":"A","Info":3},{"Id":"A","Info":4}]
       ],
   "B":[
          [{"Id":"B","Info":1},{"Id":"B","Info":2}]
       ]
}

This won't work if there are any empty arrays in TelemetryCollection. This can be fixed if FirstOrDefault() is used to retrieve the first key and defaulting to "" if there's none :

var dict=collection.GroupBy(t=>t.FirstOrDefault()?.Id??"")
                   .ToDictionary(g=>g.Key,
                                 g=>g.AsEnumerable());