You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何动态过滤对象数组,按语言提取城市计数至新结构?

动态城市场景下按语言过滤提取城市count值的实现方案

问题描述

静态场景实现

初始输入数据(固定城市为usa和japan):

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

需求:按指定语言过滤,提取对应语言下各城市的count值,生成如下结构结果:

// 过滤Alpha时
output = { japan: [0, 10], usa: [33, 20] }
// 过滤Beta时
output = { japan: [3, 15], usa: [0, 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');

动态场景需求

现在输入变为动态:城市不固定(可能新增),部分语言的details数组可能为空,示例动态输入:

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

需要生成动态结果:

// 过滤Alpha时
output = { usa: [33, 0], korea: [20, 0 ] }
// 过滤Beta时
output = { japan: [3, 15], russia: [0, 77] }

修改后的实现代码

const filterBy = (data, name) => {
    // 收集目标语言下所有出现过的城市,避免遗漏
    const allCities = new Set();
    data.forEach(item => {
        const targetLang = item.languages.find(lang => lang.name === name);
        if (targetLang?.details) {
            targetLang.details.forEach(detail => allCities.add(detail.city));
        }
    });

    // 初始化结果对象,每个城市对应一个空数组
    const result = [...allCities].reduce((acc, city) => {
        acc[city] = [];
        return acc;
    }, {});

    // 遍历每个数据项,填充对应城市的count值(无则补0)
    data.forEach(item => {
        const targetLang = item.languages.find(lang => lang.name === name);
        // 将当前项的details转为城市-计数的映射,空details则返回空对象
        const cityCountMap = targetLang?.details?.reduce((map, { city, count }) => {
            map[city] = count;
            return map;
        }, {}) || {};

        // 对每个已收集的城市,push对应值或0
        [...allCities].forEach(city => {
            result[city].push(cityCountMap[city] || 0);
        });
    });

    return result;
}

// 测试示例
const dynamicData = [
    {
        "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 } ] }
        ]
    }
];

const alphaResult = filterBy(dynamicData, 'Alpha');
const betaResult = filterBy(dynamicData, 'Beta');
console.log(alphaResult); // { usa: [33, 0], korea: [20, 0] }
console.log(betaResult); // { japan: [3, 15], russia: [0, 77] }

关键思路说明

  1. 动态收集城市:先遍历所有数据项,提取目标语言下出现的所有城市,用Set去重,确保不管新增什么城市都能被捕获。
  2. 初始化结果结构:基于收集到的城市列表,初始化每个城市对应空数组的结果对象。
  3. 填充计数数据:遍历每个数据项,将当前项的details转为城市-计数的映射,然后对每个已收集的城市,取对应计数或补0,推入结果数组中。
  4. 兼容空details:当目标语言的details为空时,cityCountMap会是一个空对象,此时所有城市都会补0,符合需求。

内容的提问来源于stack exchange,提问作者Aren Trot

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 15:53:16