Home > Enterprise >  How do I create a new list<list<object>> from a list<object> with all matching uni
How do I create a new list<list<object>> from a list<object> with all matching uni

Time:11-06

I have a list of objects. There will be many objects but some will have the same properties. I want to create a nested list of these property matches, efficiently.

Example:

List<Car> cars = [
    Car(34, 'Micro'),
    Car(23, 'Micro'),
    Car(22, 'Tomsa'),
    Car(99, 'Tomsa'),
    Car(34, 'Tikka'),
  ];

List<List<Car>> sortFunction(List<Car> list) {
...
}

class Car {
  int age;
  String name;

  Car(this.age, this.name);
  
  @override
  toString() {
    return 'Car: $age $name';
  }
}

Desired output of sort function:

[
   [
      Car(34, 'Micro'),
      Car(23, 'Micro'),
   ],
   [
      Car(22, 'Tomsa'),
      Car(99, 'Tomsa'),
   ],
   [
      Car(34, 'Tikka'),
   ],
]

What I've tried isn't even worth posting because I'm way off and can't find how to do this. But ill post anyway...

List<List<Car>> makeUniqueLists(List<Car> list) {
    List<List<Car>> uniqueLists = [];
//     for (int i = 0; i < list.length; i  ) {
//       List<Car> innerList = [];
//       for (int j = 0; j<list.length; j  ) {
//         if (list[i].name.contains(list[j].name)) {
//           innerList.add(list[i]);
//         }
//         uniqueLists.add(innerList);
//       }
//     }
    var uniqueCars = Set<String>();
    list.where((car) => uniqueCars.add(car.name)).toList();
    for (int i = 0; i < list.length; i  ) {
      if (uniqueCars.any((car) => car == list[i].name)) {
        List<Car> innerCarList = [];
        innerCarList.add(list[i]);
        uniqueLists.add(innerCarList);
      }
    }
    return uniqueLists;
  }

Gives:

[[Car: 34 Micro], [Car: 23 Micro], [Car: 22 Tomsa], [Car: 99 Tomsa], [Car: 34 Tikka]]

CodePudding user response:

The collection package, has a groupListsBy extension method you can use to group by the car name. It will collect the results as a map, but you can just return the values of that map to get a List<List<Car>>.

import 'package:collection/collection.dart';

List<Car> cars = [
  Car(34, 'Micro'),
  Car(23, 'Micro'),
  Car(22, 'Tomsa'),
  Car(99, 'Tomsa'),
  Car(34, 'Tikka'),
];

List<List<Car>> sortFunction(List<Car> list) {
  return list.groupListsBy((car) => car.name).values.toList();
}

class Car {
  int age;
  String name;

  Car(this.age, this.name);
  
  @override
  toString() {
    return 'Car: $age $name';
  }
}

void main() {
  print(sortFunction(cars));
}

Alternatively, if you don't want to rely on the collection package you can implement the same behavior like this:

List<List<Car>> sortFunction(List<Car> list) {
  Map<String, List<Car>> results = {};
  for (final car in list) {
    results.update(car.name, (list) => list..add(car), ifAbsent: () => [car]);
  }
  return results.values.toList();
}

Output:

[[Car: 34 Micro, Car: 23 Micro], [Car: 22 Tomsa, Car: 99 Tomsa], [Car: 34 Tikka]]
  • Related