i am new to flutter . I am trying to create new list from below list

 var itemlist1=[
          {"p_id": "a101", "model": "M-Plaz","price": 2500},
          {"p_id": "a101", "model": "Z-Plaz","price": 3500},
          {"p_id": "a102", "model": "M-Neo", "price": 1560},
          {"p_id": "a102", "model": "N-Neo1","price": 3600}];

Output list should be like below

var newlist=[{"Subitems":[
    {
        "p_id":"a101",
        "items": [
            {"p_id": "a101", "model": "M-Plaz","price": 2500},
          {"p_id": "a101", "model": "Z-Plaz","price": 3500}     
        ]},{
        "p_id": "a102",
        "items": [
           {"p_id": "a102", "model": "M-Neo", "price": 1560},
          {"p_id": "a102", "model": "N-Neo1","price": 3600}
        ]},
    ]
}];

please i need help..


Solution 1: Siddharth Mehra

You can do this by:

newlist.addAll([
  {'Subitems': itemlist1}
]);

print(newlist.toString());


Solution 2: nagendra nag

The below code gives you the required output.

var itemlist1 = [
      {"p_id": "a101", "model": "M-Plaz", "price": 2500},
      {"p_id": "a101", "model": "Z-Plaz", "price": 3500},
      {"p_id": "a102", "model": "M-Neo", "price": 1560},
      {"p_id": "a102", "model": "N-Neo1", "price": 3600}
    ];

    var newlist = groupBy(itemlist1, (Map obj) => obj['p_id']);

    var requiredOutput = [
      {"Subitems": []}
    ];
    newlist.forEach((k, v) => {
          requiredOutput[0]["Subitems"]!.add({"p_id": k, "items": v})
        });

    print(requiredOutput);

Note: Add import "package:collection/collection.dart"; line in imports.


Solution 3: Thierry

I would recommend you not to work directly on a Map<String, dynamic> you get from Json. You could rather define a Model for your Products.

class ProductModel {
  final String pId;
  final String model;
  final double price;

  ProductModel({
    required this.pId,
    required this.model,
    required this.price
  });

  ProductModel.fromJson(Map<String, dynamic> json):
    pId = json['p_id'] as String,
    model = json['model'] as String,
    price = json['price'] as double;

  Map<String, dynamic> toJson() => {
    'p_id': pId,
    'model': model,
    'price': price
  };
}

Note: Have a look at the json_serializable & freezed packages too.

Then, grouping your Products by id gets easier:

void main() {
  final List<ProductModel> list =[
    {"p_id": "a101", "model": "M-Plaz","price": 2500},
    {"p_id": "a101", "model": "Z-Plaz","price": 3500},
    {"p_id": "a102", "model": "M-Neo", "price": 1560},
    {"p_id": "a102", "model": "N-Neo1","price": 3600},
  ].map((item) => ProductModel.fromJson(item)).toList();
  final Map<String, List<ProductModel>> processed = list.fold({}, (pMap, productModel) => {
    ...pMap,
    productModel.pId: [...(pMap[productModel.pId] ?? []), productModel]
  });
  print(jsonEncode(processed));
}

Console log:

{"a101":[{"p_id":"a101","model":"M-Plaz","price":2500},{"p_id":"a101","model":"Z-Plaz","price":3500}],"a102":[{"p_id":"a102","model":"M-Neo","price":1560},{"p_id":"a102","model":"N-Neo1","price":3600}]}

Remark

With your Output format, in order to get the models for p_id 'a101', you will have to:

final a101Models = newlist[0]['Subitems']?.singleWhere((product) => product['p_id'] == 'a101')['items']

With my recommended solution, it gets easier:

List<ProductModel> a101Models = processed['a101'];
```


Solution 4: DeePanShu

Try this code snippet:

 var itemlist1=[
          {"p_id": "a101", "model": "M-Plaz","price": 2500},
          {"p_id": "a101", "model": "Z-Plaz","price": 3500},
          {"p_id": "a102", "model": "M-Neo", "price": 1560},
          {"p_id": "a102", "model": "N-Neo1","price": 3600}];

 // list for subItems
  var subItems = [];
  itemlist1.forEach((item){

     // check for subitem for p_id already exists or not
     List items =  subItems.where((i)=>
        i['p_id'] == (item)['p_id']
      ).toList();

      if(items.length > 0 ){
        (items[0] as Map<String,dynamic>)['items'].add(item);
      }else {
          Map newMap = Map<String,dynamic>();
          newMap.putIfAbsent('p_id', () => (item)['p_id'].toString());
          List newList = [item];
          newMap.putIfAbsent('items', () => newList);
          subItems.add(newMap);
      } 
    });

   var output = [
      {"Subitems": subItems}
    ];

  print(output);