Iterate through map values in dart / flutter

67.9k views Asked by At

I am basically from JS background and now trying my hands on flutter framework. I am stuck in formatting my data I received from API.

Data Received an array of objects

 [
   {
     "id": 1,
     "name": "name1",
     "type": "Both",
     "count": 4
   },
   {
     "id": 2,
     "name": "name2",
     "type": "Both",
     "count": 6
   },
   {
     "id": 3,
     "name": "name1",
     "type": "Both",
     "count": 2
   },
   {
     "id": 4,
     "name": "name3",
     "type": "Both",
     "count": 8
   },
   ......
 ]

My Requirement is I will have to group the data based on the name

{
  name1: [
           {
             "id": 1, "name":"name1", "type": "Both", "count": 4
           },
           {
             "id": 3, "name":"name1", "type": "Both", "count": 2
           }
  ],
  name2: [
           {
             "id": 2, "name":"name2", "type": "Both", "count": 6
           }
  ],
  .....
}

In dart, I have managed to do that grouping using groupBy from collections.dart package.

The problem is I cannot loop through the grouped data. I need to access the count for some manipulation for each grouped name.

Below is the code snipped which I tried

  Map data;
  List partySnapData;
  Map newMap;

  Future _getTopParties() async {
   final response =await http.get(API_URL + '/getPartySnapShot');
   data =json.decode(response.body);
   partySnapData = data['resultObj'];
   setState(() {
    newMap = groupBy(partySnapData, (obj) => obj['party_name']);
    for(var v in newMap.values) {
     print(v);
    }
 });

}

The print(v) actually gave me the value mapped for the map E.G

[
  { "id": 1, "name":"name1", "type": "Both", "count": 4 },
  { "id": 3, "name":"name1", "type": "Both", "count": 2 }
],
.....,
......

Now, how do I loop or iterate through the array, here the v, so that i can access the elements inside?

3

There are 3 answers

2
AudioBubble On BEST ANSWER

I found a solution to this. I am posting that, incase it helps someone.

I wanted to loop through the v to generate objects.

newMap = groupBy(partySnapData, (obj) => obj['party_name']);
for(var v in newMap.values) {
 print(v);
 //below is the solution
  v.asMap().forEach((i, value) {
    print('index=$i, value=$value');
  }
}
1
Naveen Avidi On

UPDATED

List<Map> list = [
       {
         "id": 1,
         "name": "name1",
         "type": "Both",
         "count": 4
       },
       {
         "id": 2,
         "name": "name2",
         "type": "Both",
         "count": 6
       },
       {
         "id": 3,
         "name": "name1",
         "type": "Both",
         "count": 2
       },
       {
         "id": 4,
         "name": "name3",
         "type": "Both",
         "count": 8
       }];
        Map sorted={};

      @override
      void initState(){
        super.initState();
        for(Map m in list){
          if(sorted[m['name'].toString()]==null)
            sorted[m['name'].toString()]=[];

          sorted[m['name'].toString()].add(m);

        }
      }

      @override
      Widget build(BuildContext context) {
        return Scaffold(
        body:Container(
          padding:EdgeInsets.all(20),
        color:Colors.white,
        alignment:Alignment.center,
        child:Column(
          mainAxisSize:MainAxisSize.min,
          children: <Widget>[
            Text('Original\n $list',
                      style:TextStyle(color:Colors.black)),
            SizedBox(height:15),
            Text('Sorted\n $sorted',
                      style:TextStyle(color:Colors.black)),
//EDIT
            SizedBox(height:15),
            ListView(
              shrinkWrap:true,
              children: sorted.entries.map<Widget>((value){
                return Column(
                     mainAxisSize:MainAxisSize.min,
                     crossAxisAlignment:CrossAxisAlignment.start,
                     children:[

Text(value.key.toString(),style:TextStyle(color:Colors.black,
                                                     fontWeight:FontWeight.bold)),
            Column(
            mainAxisSize:MainAxisSize.min,
            children:value.value.map<Widget>((subValue){
              return Text(subValue['count'].toString(),style:TextStyle(color:Colors.black));
            }).toList(),
            ),
          ]
          );
        }).toList(),
       )
          ],
        )
        )
        );
      }

SS

0
Dpedrinha On

Ignoring your specific case but answering the question in case others come across this question like I did while searching for How to iterate through map values in dart / flutter.

There is a simpler and a better approach.

Here's the best approach (because this way you can break the for loop after finding the right entry and doing what you had to do to avoid unnecessary iterations).

for (MapEntry<type, type> item in myMap.entries) {
  //Here each item has a key and a value proterties.
  //Don't forget to use break; to end the loop when you are done and avoid unnecessary iterations.
}

And here is the easier:

myMap.forEach((key, value) {
  //Here you have key and value for each item in your map but you can't break the loop
  //to avoid unnecessary iterations.
  //This approach is only useful when you need to perform changes in all Map items.
});