Home > Back-end >  How to group a list of objects based on nested values in Dart
How to group a list of objects based on nested values in Dart

Time:11-09

I have a list of custom objects that I want to group based on some values within the object. My code basically looks like this:

class Bar{
  String someVal;
  int num;  // group by this value

  Bar(this.someVal, this.num);
}

class Foo{
  String someVal;
  List<Bar> bars;

  Foo(this.someVal, this.bars);
}

void main()
{
  Bar bar1 = Bar("val1", 3);
  Bar bar2 = Bar("val2", 5);
  Bar bar3 = Bar("val3", 2);
  Foo foo1 = Foo("someString", [bar1, bar2, bar3]);

  Bar bar4 = Bar("val4", 2);
  Bar bar5 = Bar("val5", 3);
  Bar bar6 = Bar("val6", 1);
  Foo foo2 = Foo("someString", [bar4, bar5, bar6]);

  List<Foo> foos = [foo1, foo2];
  
  // Desired result: explicit groups by attribute 'num' in Bar
  List<Map> groupedBars =
  [{"num": 3, "bar": [bar1, bar5]},
    {"num": 2, "bar":[bar3, bar4]},
    {"num": 1, "bar": [bar6]}
  ];
}

How to get these groups efficiently without looping multiple times over these nested structures? Thanks for your help!

CodePudding user response:

Does this help?


 //Get all bars out of the foos list
 final bars = foos.map((foo) => foo.bars).expand((bars) => bars);
  
 //Get all unique numbers out of the list of bars
 final nums =  bars.map((bar) => bar.num).toSet();
    
  
 //Create the desired map by finding the bars that match num
 final desiredMap= nums.map((num) => {
   "num" : num,
   "bar" : bars.where((bar) => bar.num == num).toList()
 });

CodePudding user response:

This should work

List<Map> groupMyBars(List<Foo> myFoos) {
   Map<int, List<Bar>> groupedBarsMap = {};

   for (var foo in myFoos) {
       for (var bar in foo.bars) {
            groupedBarsMap.update(bar.num, (value) => [...value, bar], ifAbsent: () => [bar]);
       }
   }
   return groupedBarsMap.keys.fold<List<Map>>(
        [], (previousValue, element) => previousValue..add({"num": element, "bar": groupedBarsMap[element]}));
}
  • Related