I have a json list from api and need to collect count of status in list and stored in a new list. Json List from api like :
"data": [
{
"_id": "1",
"status": [
{
"status": "A",
"count": 6
},
{
"status": "B",
"count": 5
},
],
},
{
"_id": "2",
"status": [
{
"status" : "S",
"count" : 17
},
{
"status": "A",
"count": 2
},
],
}
]
I need collect count of status list like : "counts": [ { "status" : "A", "count": 8 }, { "status" : "B", "count": 5 }, { "status" : "S", "count": 17 },
]
I made a slightly shorter version, with updating list elements instead of deleting and adding again. See the change between the lines below.
Then, I've also added a bonus at the end! 🙂
void main() async {
Map mapFromIpa = {
"data": [
{
"_id": "1",
"status": [
{
"status": "A",
"count": 6
},
{
"status": "B",
"count": 5
},
],
},
{
"_id": "2",
"status": [
{
"status" : "S",
"count" : 17
},
{
"status": "A",
"count": 2
},
],
}
]
};
List data = mapFromIpa["data"];
List listOfStatusMap = [];
List<Map> summedUpCounts = [];
for (Map idMap in data) {
for (Map statusMap in idMap["status"]) {
listOfStatusMap.add(statusMap);
}
}
print(listOfStatusMap);
for (Map statusMap in listOfStatusMap) {
bool statusAlreadyExists = false;
late int sum;
int? updateIndex; // Changed the name here...
for (Map sumMap in summedUpCounts) {
// If a map with the same status value already exists in the summedUpCounts list:
if (sumMap.containsValue(statusMap['status'])) {
print('Status ${statusMap['status']} already exists in summedUpCounts!');
statusAlreadyExists = true;
sum = sumMap['count'] + statusMap['count']; // Old value added to new value of count
updateIndex = summedUpCounts.indexOf(sumMap); // You can't remove here, since you are still looping through this List!
break; // We can break this for-loop, coz there's not supposed to be TWO maps
// with the same status in the summedUpCounts, ever!
}
}
// Very important that this code be placed outside the inner for-loop!
if (statusAlreadyExists) {
//-------------------------------------------------
// New alternative solution:
summedUpCounts[updateIndex!] = {
'status': statusMap['status'],
'count': sum
};
//-------------------------------------------------
// My old version:
// summedUpCounts.removeAt(updateIndex!); // You CAN remove a map value (summedUpCounts.remove(value)),
// // but... this sometimes causes issues because of how flutter treats equalities with Maps. Index is safer!
// summedUpCounts.add({
// 'status': statusMap['status'],
// 'count': sum
// });
} else {
summedUpCounts.add(statusMap);
}
}
print(summedUpCounts);
The new output is:
[
{status: A, count: 8}
{status: B, count: 5},
{status: S, count: 17},
]
(The old output was:
[
{status: B, count: 5},
{status: S, count: 17},
{status: A, count: 8}
]
)
Feel free to put that in a Map like:
Map finalMap = {
'counts': summedUpCounts
};
if you like! 😉
Edit:
As a bonus, I was just thinking: Wouldn't it be easier for you to have the info in a Map looking like this instead:
{
'A': 8,
'B': 5,
'S': 17
}
? Then YOU will know that the keys are statuses and the values are counts, without the need to keep the words "status" and "count" in the Object!
If you want this, you can exchange the code from print(listOfStatusMap);
above with:
print(listOfStatusMap);
Map statusAndCount = {};
for (Map statusMap in listOfStatusMap) {
bool statusAlreadyExists = false;
late int sum;
for (String status in statusAndCount.keys) {
// If the same status already exists in the statusAndCount Map:
if (statusMap['status'] == status) {
print('Status $status already exists in statusAndCount Map!');
statusAlreadyExists = true;
sum = statusAndCount[status] + statusMap['count']; // Old value added to new value of count
break; // We can break this for-loop, coz there's not supposed to be TWO keys
// with the same status in the statusAndCount, ever!
}
}
// Very important that this code be placed outside the inner for-loop!
if (statusAlreadyExists) {
statusAndCount[statusMap['status']] = sum;
} else {
statusAndCount.addAll({
statusMap['status']: statusMap['count']
});
}
}
print(statusAndCount);
Now, the output is:
{
A: 8,
B: 5,
S: 17
}
Seems all of your code will be shorter from here, if you do it this way...! 🙂