I have a sales List like below:
List<Map<String,dynamic>> sales = [
{'paid': 2000, 'name': 'person1'},
{'paid': 2500, 'name': 'person2'},
{'paid': 5600, 'name': 'person1'},
{'paid': 974.0, 'name': 'person2'},
];
I want to sum persons' paid amount and show in a ListView.builder like below:
person1 : 7600 person2 : 3474
I need a hand with how to calculate every individual person inside a map in Dart/Flutter.
Thanks in advance.
CodePudding user response:
I would go with a method a bit more verbose but that would allow you top keep a reference on your results.
final List<Map<String, dynamic>> sales = [
{'paid': 2000, 'name': 'person1'},
{'paid': 2500, 'name': 'person2'},
{'paid': 5600, 'name': 'person1'},
{'paid': 974.0, 'name': 'person2'},
];
final salesByName = <String, List<Map<String, dynamic>>>{};
for (final entry in sales) {
if (salesByName.keys.contains(entry["name"] as String)) {
salesByName[entry["name"] as String]?.add(entry);
} else {
salesByName[entry["name"] as String] = [entry];
}
}
final salesByNameSum = <String, double>{};
for (final name in salesByName.entries) {
print("${name.key} has ${name.value.length} entries");
double sum = 0.0;
for (final sale in name.value) {
sum = sale['paid'] as double;
}
salesByNameSum[name.key] = sum;
}
for (final entry in salesByNameSum.entries) {
print('${entry.key}: ${entry.value}');
}
You would first create a map using name
as a key and containing a list of sales maps in its value. That way you can easily access the list of each person's transactions.
Then, you could create another smaller map, containing exclusively the name
as its key, and the sum
as its value.
Here is a pure-dart DartPad as an example : https://dartpad.dev/?id=2f4e9b102ba931846bc8734c1180b29f
Hope it helps!
CodePudding user response:
this code might help you:
void main() {
List<Map<String, dynamic>> sales = [
{'paid': 2000, 'name': 'person1'},
{'paid': 2500, 'name': 'person2'},
{'paid': 5600, 'name': 'person1'},
{'paid': 974.0, 'name': 'person2'},
];
Map map = Map();
for (var sale in sales) {
if (map.keys.contains(sale['name'])) {
map[sale["name"]] = map[sale["name"]] sale['paid'];
} else
map[sale["name"]] = sale['paid'];
}
print(map.toString());
}
where the output would be:
{person1: 7600, person2: 3474.0}
CodePudding user response:
There is another way to do it. Following the method used on this answer, with some additional changes into the logic:
void main() {
List<Map<String, dynamic>> sales = [
{'paid': 2000, 'name': 'person1'},
{'paid': 2500, 'name': 'person2'},
{'paid': 5600, 'name': 'person1'},
{'paid': 974.0, 'name': 'person2'},
];
var result = sales.groupBy((m) => m['name']).map(
(key, value) => MapEntry(
key,
value.fold<double>(0.0, (a, b) => a b['paid']),
),
);
print(result);
}
// use this extension
extension Iterables<E> on Iterable<E> {
Map<K, List<E>> groupBy<K>(K Function(E) keyFunction) => fold(
<K, List<E>>{},
(Map<K, List<E>> map, E element) =>
map..putIfAbsent(keyFunction(element), () => <E>[]).add(element));
}
it will produce something like this:
{person1: 7600.0, person2: 3474.0}
You can try to run it on dartpad.