I have an complex list but I need to merge them plz help me..
var itemlist1=[
{"p_id": "a101", "p_name": "item1","type": "finished"},
{"p_id": "a102", "p_name": "item2","type": "s-finished"},
{"p_id": "b101", "p_name": "item3","type": "finished"},
{"p_id": "c105", "p_name": "item4","type": "finished"}];
var itemlist2=[
{"p_id": "a101", "type": "finished", "quantity": 605, "price": 1200},
{"p_id": "a102", "type": "semi finished", "quantity": 150, "price": 950},
{"p_id": "c105", "type": "finished", "quantity": 560, "price":665}];
i need list like below.
var itemlist3=[
{"p_id": "a101", "p_name": "item1", "type": "finished", "quantity": 605, "price": 1200},
{"p_id": "a102", "p_name": "item2", "type": "s-finished", "quantity": 150, "price": 950},
{"p_id": "b101", "p_name": "item3", "type": "finished", "quantity": 0, "price": 0},
{"p_id": "c105", "p_name": "item4", "type": "finished", "quantity": 560, "price":665}];
how to achive this ? help me..
CodePudding user response:
Ok so your result list takes the p_id
, p_name
and type from the first list, like this:
List<Map<String, dynamic>> result = itemList1.map((item) {
var resultItem = Map.from(item);
return resultItem;
});
However you also want to add quantity
and price
from the second list, like this:
List<Map<String, dynamic>> result = itemList1.map((item) {
var resultItem = Map.from(item);
var list2Obj = itemList2.firstWhereOrNull((value) => value['p_id'] == item['p_id']);
var quantity = list2Obj != null ? list2Obj['quantity'] : 0;
var price = list2Obj != null ? list2Obj['price'] : 0;
resultItem['quantity'] = quantity;
resultItem['price'] = price;
return resultItem;
});
I used the firstWhereOrNull
function from the package:collection
module. If you don't want to use it, here is a simple implementation:
T? firstWhereOrNull<T>(List<T> list, bool Function(T) fun) {
try {
return list.FirstWhere(fun);
} on StateError {
return null;
}
}
I can't test the implementation right now, but it should work
CodePudding user response:
You can achive it by looping one of the list and getting its corresponding value from the other list. Then merge them.
var itemlist1 = [
{"p_id": "a101", "p_name": "item1","type": "finished"},
{"p_id": "a102", "p_name": "item2","type": "s-finished"},
{"p_id": "b101", "p_name": "item3","type": "finished"},
{"p_id": "c105", "p_name": "item4","type": "finished"}];
var itemlist2 = [
{"p_id": "a101", "type": "finished", "quantity": 605, "price": 1200},
{"p_id": "a102", "type": "semi finished", "quantity": 150, "price": 950},
{"p_id": "c105", "type": "finished", "quantity": 560, "price":665}];
var itemlist3 = itemlist2.map((map){
var _matches = itemlist1.where((val)=> val['p_id'] == map['p_id']);
if(_matches.isNotEmpty){
return {..._matches.first, ...map};
}
}).toList();
CodePudding user response:
You want to merge two List<Map>
s such that Map
s that have the same p_id
value are combined. To make it easy and fast to find an existing Map
from a p_id
value, it'd help to first create a Map<String, Map>
to use as a lookup table to map p_id
values to Map
s. As we iterate over the List
s, we'll merge each Map
with an existing entry in the table. Two Map
s can be easily merged with the spread operator.
Once that's done, we can create a List<Map>
from the values of the table.
For example:
var itemlist1 = <Map<String, dynamic>>[
{"p_id": "a101", "p_name": "item1", "type": "finished"},
{"p_id": "a102", "p_name": "item2", "type": "s-finished"},
{"p_id": "b101", "p_name": "item3", "type": "finished"},
{"p_id": "c105", "p_name": "item4", "type": "finished"}
];
var itemlist2 = <Map<String, dynamic>>[
{"p_id": "a101", "type": "finished", "quantity": 605, "price": 1200},
{"p_id": "a102", "type": "semi finished", "quantity": 150, "price": 950},
{"p_id": "c105", "type": "finished", "quantity": 560, "price": 665}
];
void main() {
var mergedMap = <String, Map<String, dynamic>>{};
// Instead of `itemlist1 itemlist2`, alternatively use CombinedIterableView
// from package:collection to avoid allocating a new `List`.
for (var map in itemlist1 itemlist2) {
var id = map['p_id']!;
var existingEntry = mergedMap[id] ?? {};
mergedMap[id] = {...existingEntry, ...map};
}
var itemlist3 = mergedMap.values.toList();
print(itemlist3);
}
Presuming that there's a constant number of entries for each Map
, this approach should be O(m n) where m and n are the sizes of the two List<Map>
s to merge.