WatsMyName
WatsMyName

Reputation: 4478

Flutter/Dart group list by date

I have following list of maps,

[
   {
      "FullName":"Harry Potter",
      "DateOfBirth": "2020/02/16",
      "Department":"Branch Operation",
      "BirthDay":"Friday"
   },
   {
      "FullName":"John Wick",
      "DateOfBirth": "2020/02/16",
      "Department":"Finance",
      "BirthDay":"Friday"
   },
   {
      "FullName":"Solomon Kane",
      "DateOfBirth":2020/02/19,
      "Department":"Loan",
      "BirthDay":"Monday"
   }
]

I would like to manipulate above data such that data are grouped by their DateOfBirth, so that result would look like this.

[
   {
      "DateOfBirth": "2020/02/16",
      "BirthDay": "Friday",
      "Data":[
         {
            "FullName": "Harry Potter",
            "Department":"Branch Operation",
         },
         {
            "FullName":"John Wick",
            "Department":"Finance",
         }
      ]
   },
   {
      "DateOfBirth": "2020/02/19",
      "BirthDay": "Monday",
      "Data":[
         {
            "FullName":"Solomon Kane",
            "Department":"Loan"
         }
      ]
   },
]

In Javascript, this can be achieved by using reduce function and then using Object key mapping. I also know dart has useful package called collection

As I am new to dart and flutter, I am not sure how to do. Can anybody help me on this?

Thanks

Upvotes: 1

Views: 6743

Answers (2)

Max Bykov
Max Bykov

Reputation: 53

Had the same question. The best solution: use inner extentions. See IterableExtension

Update pubspec.yaml and use it.

https://api.flutter.dev/flutter/package-collection_collection/IterableExtension/groupListsBy.html

pubspec.yaml
...
dependencies:
  collection: any
      final Map<String, List<ItemType>> result =
          data.groupListsBy((item) => item.timeField.year.toString());

Upvotes: 0

gugge
gugge

Reputation: 948

You could use fold and do something like this

const data = [...];

void main() {
 final value = data.fold(Map<String, List<dynamic>>(), (Map<String, List<dynamic>> a, b) {
   a.putIfAbsent(b['DateOfBirth'], () => []).add(b);
   return a;
 }).values
   .where((l) => l.isNotEmpty)
   .map((l) => {
     'DateOfBirth': l.first['DateOfBirth'],
     'BirthDay': l.first['BirthDay'],
     'Data': l.map((e) => {
       'Department': e['Department'],
       'FullName': e['FullName'],
     }).toList()
 }).toList();
}

Or like this if you want to use the spread operator, I don't know if its very readable though.

 final result = data.fold({}, (a, b) => {
     ...a,
     b['DateOfBirth']: [b, ...?a[b['DateOfBirth']]],
 }).values
   .where((l) => l.isNotEmpty)
   .map((l) => {
     'DateOfBirth': l.first['DateOfBirth'],
     'BirthDay': l.first['BirthDay'],
     'Data': l.map((e) => {
       'Department': e['Department'],
       'FullName': e['FullName'],
     }).toList()
 }).toList();

Upvotes: 11

Related Questions