I have a List<Map>
that I need the IDs to be distinct in the list and obtain a cumulative value for each ID.
What I currently have works, but I was wondering if there is a cleaner way to do this?
My code:
List tagId = ['a', 'b'];
List oldList = [{'id': 'a', 'value': 1},
{'id': 'a', 'value': 1},
{'id': 'a', 'value': 1},
{'id': 'a', 'value': 1},
{'id': 'b', 'value': 1},
{'id': 'b', 'value': 1}];
List newList = [];
for(final i in tagId) {
int totalValue = 0;
for(final d in oldList){
if(i == d['id']){
totalValue ;
}
}
newList.add({'id': i, 'value': totalValue});
}
print(newList);
CodePudding user response:
I'm assuming that you wrote the tagList
manually, you don't want to do that manually or from another unnecessary algorithm that will result in it.
If you need just access to the id
and value
, then you probably want to avoid an O(N^2)
algorithm, I wrote an O(N)
that might help for better performance:
Map<String, int> map = {};
for(int index = 0; index < oldList.length; index =1) {
map[oldList[index]["id"]] = (map[oldList[index]["id"]] ?? 0) oldList[index]["value"] as int;
}
print(map); // {a: 4, b: 2}
and if you need the same result then you can just add this:
List<Map> asMapList = [];
map.forEach((key, value) {
asMapList.add({"id": key, "value": value});
} );
print(asMapList); // [{id: a, value: 4}, {id: b, value: 2}]
CodePudding user response:
You can also:
- Merge/reduce the array list elements into a single
Map
. - Generate the list from the merged
Map
.
void main() {
List tagId = ['a', 'b'];
List<Map<String, dynamic>> oldList = [
{'id': 'a', 'value': 1},
{'id': 'a', 'value': 1},
{'id': 'a', 'value': 1},
{'id': 'a', 'value': 1},
{'id': 'b', 'value': 1},
{'id': 'b', 'value': 1}
];
// reduce uses the first element as initialValue, so I added an empty map
// as the initial value, to start merging from the second element (second element here, but it's your actual first element)
final merged = ([{}] oldList).reduce(
(map, e) => map..[e['id']] = (map[e['id']] ?? 0) (e['value'] ?? 0),
);
var mergedAsList =
merged.keys.map((key) => {'id': key, 'value': merged[key]});
print(mergedAsList); // Same output as yours
}