我输入如下
[
{
"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 } ] },
]
},
]
所以这是我的场景,我必须按语言 Alpha 进行过滤。所以我必须通过 Alpha 遍历第一个对象和过滤语言,然后将美国和日本计数到一个新数组中。同样循环第二个对象并提取该计数。
最后,我应该得到低于新数组中的计数序列
output = { japan: [0, 10], usa: [33, 20] } //for filter by Alpha
output = { japan: [3, 15], usa: [0, 25] } //for filter by Beta
我可以使用以下代码实现上述输出。
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');
到这里为止一切都工作正常。如果输入是动态的,就会出现问题。即我们不知道输出是否只包含
japan
和 usa
(它不是静态的)
这是我现在期待的动态输入,而不是之前的静态输入。
[
{
"metadata": { "id": 1071, "name": "First" },
"languages": [
{ "name": "Alpha", "details": [ { "city": "usa", "count": 33 }, { "city": "korea", "count": 20 } ] },
{ "name": "Beta", "details": [ { "city": "japan", "count": 3 } ] },
]
},
{
"metadata": { "id": 1068, "name": "Second" },
"languages": [
{ "name": "Alpha", "details": [] },
{ "name": "Beta", "details": [ { "city": "japan", "count": 15 }, { "city": "russia", "count": 77 } ] },
]
},
]
根据上述输入,某些
languages
可能包含其他对象中不存在的其他城市。还有一些可能是空的details:[]
对于上述输入,我想要所需的输出
output = { usa: [33, 0] korea: [20, 0 ] } //for filter by Alpha
output = { japan: [3, 15], russia: [0, 77] } //for filter by Beta
有人可以让我知道如何动态获取它吗?
您可以减少数组并从嵌套项中获取信息。
const
filter = (array, value) => array.reduce((r, { languages }, i, a) => {
languages.some(({ name, details }) => {
if (name === value) {
details.forEach(({ city, count }) => {
r[city] ??= Array(a.length).fill(0);
r[city][i] = count;
})
return true;
}
});
return r;
}, {}),
data = [
{
"metadata": { "id": 1071, "name": "First" },
"languages": [
{ "name": "Alpha", "details": [ { "city": "usa", "count": 33 }, { "city": "korea", "count": 20 } ] },
{ "name": "Beta", "details": [ { "city": "japan", "count": 3 } ] },
]
},
{
"metadata": { "id": 1068, "name": "Second" },
"languages": [
{ "name": "Alpha", "details": [] },
{ "name": "Beta", "details": [ { "city": "japan", "count": 15 }, { "city": "russia", "count": 77 } ] },
]
},
],
result1 = filter(data, 'Alpha'),
result2 = filter(data, 'Beta');
console.log(result1);
console.log(result2);
.as-console-wrapper { max-height: 100% !important; top: 0; }