简体   繁体   中英

Flutter/Dart how to groupBy list of maps from json

This question is almost identical to the one answered here The difference is that my data is json , coming from an API call. This is causing the error shown at the bottom of the code below. I've tried various combinations of casting and variable types with no success.

        import 'dart:convert';
        import "package:collection/collection.dart";
        
        void main(List<String> args) {
          var data1 = [
            {"title": 'Avengers', "release_date": '10/01/2019'},
            {"title": 'Creed', "release_date": '10/01/2019'},
            {"title": 'Jumanji', "release_date": '30/10/2019'},
          ];
           //without these two lines, the code executes with no problems
          var data2 = jsonEncode(data1);
          var data3 = jsonDecode(data2);
        
          try {
            var newMap = groupBy(data3, (Map obj) => obj['release_date']);
            print(newMap);
          } catch (err) {
            print(err);
          }
    
    **type 'List<dynamic>' is not a subtype of type 'Iterable<Map<dynamic, dynamic>>'**




  [1]: https://stackoverflow.com/a/54036449/3185563

The static and runtime type of data1 is List<Map<String, String>> , which is inferred from the contents of the literal.

The runtime type of data3 is List<dynamic> , because that's what jsonDecode creates. The static type is just dynamic .

You can't pass a List<dynamic> to something expecting an Iterable<Map> , which is what your groupBy expects (inferred just from the (Map obj) =>... function since the other argument has type dynamic ), and why you get the error.

You can type data3 as List data3 = jsonDecode(...); . That will likely force type inference to guess dynamic as the type argument to groupBy . Then you will get an error that (Map obj) =>... doesn't accept dynamic , though.

You can, with or without the above, change (Map obj) into (dynamic obj) , that should make the code run, by skipping the type checking. Or you can do (dynamic obj) => (obj as Map)["release_date"] to do the cast before the lookup.

You can type data3 as List and then cast it to List<Map> by doing data3.cast<Map>().groupBy((Map obj) =>...) . (You can use groupBy as an extension method too, I recommend doing so, but it only works if the receiver, data3 , has a non- dynamic type.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM