Flutter / Dart如何分组按地图列表

时间:2019-01-03 20:30:29

标签: dart flutter

我有这张地图清单。

[
    {title: 'Avengers', release_date: '10/01/2019'},
    {title: 'Creed', release_date: '10/01/2019'}
    {title: 'Jumanji', release_date: '30/10/2019'},
]

我想编写这样的代码,像这样按release_date对电影列表进行分组。

[
    {'10/01/2019':  [
                  {title: 'Avengers'},
                  {title: 'Creed'}
              ]
  },

   {'30/10/2019': [
                  {title: 'Jumanji'}
              ]
 }
]

8 个答案:

答案 0 :(得分:21)

如果您具有 Dart 2.7 ,则可以扩展 Iterable以添加有用的groupBy方法:

extension Iterables<E> on Iterable<E> {
  Map<K, List<E>> groupBy<K>(K Function(E) keyFunction) => fold(
      <K, List<E>>{},
      (Map<K, List<E>> map, E element) =>
          map..putIfAbsent(keyFunction(element), () => <E>[]).add(element));
}

现在,您是地图列表,可以使用类似以下内容的分组方式:

final releaseDateMap = listOfMaps.groupBy((m) => m['release_date'])

像这样的数据:

[
    {title: 'Avengers', release_date: '10/01/2019'},
    {title: 'Creed', release_date: '10/01/2019'}
    {title: 'Jumanji', release_date: '30/10/2019'},
]

将变成:

{
  '10/01/2019': [
    {title: 'Avengers', release_date: '10/01/2019'},
    {title: 'Creed', release_date: '10/01/2019'}
  ],
  '30/10/2019': [
    {title: 'Jumanji', release_date: '30/10/2019'},
  ]
}

答案 1 :(得分:3)

软件包collection实现  groupBy函数。

按日期分组:

import "package:collection/collection.dart";

main(List<String> args) {
  var data = [
    {"title": 'Avengers', "release_date": '10/01/2019'},
    {"title": 'Creed', "release_date": '10/01/2019'},
    {"title": 'Jumanji', "release_date": '30/10/2019'},
  ];


  var newMap = groupBy(data, (obj) => obj['release_date']);

  print(newMap);
}

要从每个地图条目中删除release_date键:

var newMap = groupBy(data, (obj) => obj['release_date']).map(
    (k, v) => MapEntry(k, v.map((item) { item.remove('release_date'); return item;}).toList()));

更改键:

var newMap = groupBy(data, (obj) => obj['release_date']).map(
    (k, v) => MapEntry(k, v.map((item) => {'name': item['title']}).toList()));

答案 2 :(得分:2)

这是一种天真的实现的方法(以防您不想使用collections包中的groupBy函数):

List<Map<String, List<Map<String, String>>>> MapByKey(String keyName, String newKeyName, String keyForNewName, List<Map<String,String>> input) {
  Map<String, Map<String, List<Map<String, String>>>> returnValue = Map<String, Map<String, List<Map<String, String>>>>();
  for (var currMap in input) {
    if (currMap.containsKey(keyName)) {
      var currKeyValue = currMap[keyName];
      var currKeyValueForNewName = currMap[keyForNewName];
      if (!returnValue.containsKey(currKeyValue)){
        returnValue[currKeyValue] = {currKeyValue : List<Map<String, String>>()};  
      }
      returnValue[currKeyValue][currKeyValue].add({newKeyName : currKeyValueForNewName});
    }
  }
  return returnValue.values.toList();
}

void main() {
    var test = [
    {"title": 'Avengers', "release_date": '10/01/2019'},
    {"title": 'Creed', "release_date": '10/01/2019'},
    {"title": 'Jumanji', "release_date": '30/10/2019'},
  ];

  var testMapped = MapByKey("release_date", "name", "title", test);

  print("$testMapped");
}

输出为:

[
    {
        10/01/2019: [
            {name: Avengers
            },
            {name: Creed
            }
        ]
    },
    {
        30/10/2019: [
            {name: Jumanji
            }
        ]
    }
]

答案 3 :(得分:1)

这可能不是最佳解决方案。但这可以给你一个主意

List arrayData = [
  {"name": 'John', "gender": 'male'},
  {"name": 'James', "gender": 'male'},
  {"name": 'Mary', "gender": 'female'}
];

按性别检索列表

List males = arrayData.where((o) => o['gender'] == "male").toList();
List females = arrayData.where((o) => o['gender'] == "female").toList();

使用所需格式制作新地图:

List result = [
  {
    "male": males.map((f) => {"name": f['name']}).toList()
  },
  {
    "female": females.map((f) => {"name": f['name']}).toList()
  }
];

打印:

debugPrint('${result}');

结果:

[{male: [{name: John}, {name: James}]}, {female: [{name: Mary}]}]

答案 4 :(得分:1)

extension UtilListExtension on List{
  groupBy(String key) {
    try {
      List<Map<String, dynamic>> result = [];
      List<String> keys = [];

      this.forEach((f) => keys.add(f[key]));

      [...keys.toSet()].forEach((k) {
        List data = [...this.where((e) => e[key] == k)];
        result.add({k: data});
      });

      return result;
    } catch (e, s) {
      printCatchNReport(e, s);
      return this;
    }
  }
}

然后像这样使用它

var data = [
    {"title": 'Avengers', "release_date": '10/01/2019'},
    {"title": 'Creed', "release_date": '10/01/2019'},
    {"title": 'Jumanji', "release_date": '30/10/2019'},
];

var result = data.groupBy('title');
print(result);

那么结果就是

[{10/01/2019: [{title: Avengers, release_date: 10/01/2019}, {title: Creed, release_date: 10/01/2019}]}, {30/10/2019: [{title: Jumanji, release_date: 30/10/2019}]}]

答案 5 :(得分:0)

许多不同类型的转换可以应用于指定的数据序列。

import 'package:queries/collections.dart';

main(List<String> args) {
  var c = Collection([
    {"title": 'Avengers', "release_date": '10/01/2019'},
    {"title": 'Creed', "release_date": '10/01/2019'},
    {"title": 'Jumanji', "release_date": '30/10/2019'},
  ]);

  var result = c
      .groupBy$1((e) => e["release_date"], (e) => {"title": e["title"]})
      .toDictionary$1((e) => e.key, (e) => e.toList());

  var keyValuePairs = result.toList();
  print("List of key and value pairs:");
  print(keyValuePairs);

  var map = result.toMap();
  print("Map of transformed elements:");
  print(map);

  var result2 = c
      .groupBy((e) => e["release_date"])
      .select((e) => {"${e.key}": e.toList()});

  print("Map of original elements:");
  print(result2.toList());
}

结果:

List of key and value pairs:
[10/01/2019 : [{title: Avengers}, {title: Creed}], 30/10/2019 : [{title: Jumanji}]]
Map of transformed elements:
{10/01/2019: [{title: Avengers}, {title: Creed}], 30/10/2019: [{title: Jumanji}]}
Map of original elements:
[{10/01/2019: [{title: Avengers, release_date: 10/01/2019}, {title: Creed, release_date: 10/01/2019}]}, {30/10/2019: [{title: Jumanji, release_date: 30/10/2019}]}]

答案 6 :(得分:0)

使用supercharged软件包,您可以这样编写:

List list = [
  { title: 'Avengers', release_date: '10/01/2019' },
  { title: 'Creed', release_date: '10/01/2019' }
  { title: 'Jumanji', release_date: '30/10/2019' },
];

final map = list.groupBy<String, Map>((item) => 
  item['release_date'],
  valueTransform: (item) => item..remove('release_date'),
);

答案 7 :(得分:0)

如果您遇到此问题,要添加到已接受的答案中,在 flutter 2 中,您将收到一个错误,正如我所知道的。

The operator '[]' isn't defined for the type 'dynamic Function(dynamic)'

使用

var data = [
     {"title": 'Avengers', "release_date": '10/01/2019'},
     {"title": 'Creed', "release_date": '10/01/2019'},
     {"title": 'Jumanji', "release_date": '30/10/2019'},
   ];


   var newMap = groupBy(data, (Map oj) => oj['release_date']);

   print(newMap);

这可能对某人有帮助。