我有一个复杂的列表,但我需要合并它们,请帮助我。
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=[
{"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}];
如何实现这一点?帮帮我…
好的,所以您的结果列表采用p_id
、p_name
,并从第一个列表中键入,如下所示:
List<Map<String, dynamic>> result = itemList1.map((item) {
var resultItem = Map.from(item);
return resultItem;
});
但是,您也希望从第二个列表中添加quantity
和price
,如下所示:
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;
});
我使用了package:collection
模块中的firstWhereOrNull
函数。如果你不想使用它,这里有一个简单的实现:
T? firstWhereOrNull<T>(List<T> list, bool Function(T) fun) {
try {
return list.FirstWhere(fun);
} on StateError {
return null;
}
}
我现在不能测试实现,但它应该可以工作
您希望合并两个List<Map>
,以便合并具有相同p_id
值的Map
。为了方便快捷地从p_id
值中找到现有的Map
,首先创建一个Map<String, Map>
作为查找表,将p_id
值映射到Map
s会有所帮助。当我们迭代List
s时,我们将把每个Map
与表中的现有条目合并。两个Map
可以很容易地与扩展算子合并。
完成后,我们可以根据表的值创建一个List<Map>
。
例如:
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);
}
假设每个Map
有恒定数量的条目,这种方法应该是O(m+n(,其中m和n是要合并的两个List<Map>
的大小。
您可以通过循环其中一个列表并从另一个列表中获取相应的值来实现它。然后合并它们。
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();