I have input as follows
[
{
"metadata": { "id": 1071, "name": "First" },
"languages": [
{ "name": "Alpha", "details": [ { "city": "usa", "count": 33 } ] },
{ "name": "Beta", "details": [ { "city": "japan", "count": 3 } ] },
]
},
{
"metadata": { "id": 1068, "name": "Second" },
"languages": [
{ "name": "Alpha", "details": [ { "city": "japan", "count": 10 }, { "city": "usa", "count": 20 } ] },
{ "name": "Beta", "details": [ { "city": "japan", "count": 15 }, { "city": "usa", "count": 25 } ] },
]
},
]
So here is my scenario where i have to filter by language Alpha
. So i have to go through first object and filter languages by Alpha
and then get usa
and japan
count into a new array. Similarly loop through 2nd object and extract that count.
At the end, i should get below sequence of counts in the new array
output = { japan: [0, 10], usa: [33, 20] } //for filter by Alpha
output = { japan: [3, 15], usa: [0, 25] } //for filter by Beta
As you can see if the details
array doesnot have japan
or usa
count in it, we are pushing 0 for that.
I tried the following but couldnot achieve the desired result using reduce. Am i missing anything here ?
let output = input.reduce(
(result, { languages }) => {
result.japan.push(languages.details.count || 0);
result.usa.push(languages.details.count || 0);
return result;
},
{ japan: [], usa: [] }
);
result.japan.push(languages.details.count || 0);
This wont work, details
is an array, so you can't call .count
on it.
You'll need to loop over the details
and then add the count
for each city
, However, you need to catch the missing state.
I've used an inner reduce to map the details
array to an city/count object.
This way you can change your attempt to:
p.usa.push(groupedOnCityCount?.usa || 0);
p.japan.push(groupedOnCityCount?.japan || 0);
to catch the missing country.
This Demo should get you started:
const data = [
{
"metadata": { "id": 1071, "name": "First" },
"languages": [
{ "name": "Alpha", "details": [ { "city": "usa", "count": 33 } ] },
{ "name": "Beta", "details": [ { "city": "japan", "count": 3 } ] },
]
},
{
"metadata": { "id": 1068, "name": "Second" },
"languages": [
{ "name": "Alpha", "details": [ { "city": "japan", "count": 10 }, { "city": "usa", "count": 20 } ] },
{ "name": "Beta", "details": [ { "city": "japan", "count": 15 }, { "city": "usa", "count": 25 } ] },
]
},
];
const filterBy = (data, name) => {
return data.reduce((p, c) => {
for (let langObj of c.languages) {
if (langObj.name === name) {
const groupedOnCityCount = langObj.details.reduce((x, {city,count}) => ({ ...x, [city]: count }), {});
p.usa.push(groupedOnCityCount?.usa || 0);
p.japan.push(groupedOnCityCount?.japan || 0);
}
}
return p;
}, { japan: [], usa: [] });
}
const A = filterBy(data, 'Alpha');
const B = filterBy(data, 'Beta');
console.log(A, B);