过滤对象数组并将属性动态获取到新数组中

问题描述 投票:0回答:1

我输入如下

[
    {
        "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

有人可以让我知道如何动态获取它吗?

javascript reactjs arrays json loops
1个回答
0
投票

您可以减少数组并从嵌套项中获取信息。

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; }

© www.soinside.com 2019 - 2024. All rights reserved.