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

如何按city和country多键分组对象数组并生成子集数组?

按城市+国家分组JavaScript对象数组

我有如下JavaScript对象数组:

const array = [
    {city: 'Auckland', country: 'New Zealand', date: '2024-02-03T00:00:00'},
    {city: 'Manchester', country: 'United Kingdom', date: '2024-02-04T00:00:00'},
    {city: 'Manchester', country: 'United Kingdom', date: '2024-02-09T00:00:00'},
    {city: 'Edinburgh', country: 'Scotland', date: '2024-02-05T00:00:00'},
    {city: 'Manchester', country: 'United States', date: '2024-02-03T00:00:00'},
    {city: 'Manchester', country: 'United States', date: '2024-02-09T00:00:00'}
]

我希望将其按如下结构分组(注:示例中最后一个分组的item为笔误,以下实现统一使用items):

[
    {
        city: 'Auckland',
        items: [
            {city: 'Auckland', country: 'New Zealand', date: '2024-02-03T00:00:00'}
        ]
    },
    {
        city: 'Manchester',
        items: [
            {city: 'Manchester', country: 'United Kingdom', date: '2024-02-04T00:00:00'},
            {city: 'Manchester', country: 'United Kingdom', date: '2024-02-09T00:00:00'}
        ]
    },
    {
        city: 'Edinburgh',
        items: [
            {city: 'Edinburgh', country: 'Scotland', date: '2024-02-05T00:00:00'}
        ]
    },
    {
        city: 'Manchester',
        items: [
            {city: 'Manchester', country: 'United States', date: '2024-02-03T00:00:00'},
            {city: 'Manchester', country: 'United States', date: '2024-02-09T00:00:00'}
        ]
    }
]

我尝试了两种方法但都未成功:
第一种仅按城市分组,未考虑国家:

array.reduce((r, item) => {
    r[item.city] = r[item.city] || []
    r[item.city].push(item)

    return r
}, Object.create(null))

第二种逻辑存在问题,仅返回目标分组的第一个元素:

const cities = {};

for (let p of array) {
  const { city, country } = p;
  const groupByCity = JSON.stringify([city]);
  const groupByCountry = JSON.stringify([country]);
  if (!(groupByCity in cities)) {
    cities[groupByCity] = { city: city, items: []};
    cities[groupByCity].items.push(p);
  } else if (groupByCity in examCities && cities[groupByCity].country !== p.country) {
    cities[`${groupByCity}2`] = { city: city, items: []};
    cities[`${groupByCity}2`].items.push(p);
  }
}

现寻求正确的实现方案。


正确实现方案

核心思路是用city+country的组合作为唯一分组键,避免同名城市归属不同国家时的分组冲突,最后将分组对象转为目标数组结构。

方法一:使用Array.reduce实现

const grouped = Object.values(array.reduce((acc, item) => {
    // 拼接城市和国家作为唯一标识键
    const key = `${item.city}_${item.country}`;
    if (!acc[key]) {
        acc[key] = {
            city: item.city,
            items: []
        };
    }
    acc[key].items.push(item);
    return acc;
}, {}));

console.log(grouped);

方法二:使用for...of循环实现

const groups = {};
for (const item of array) {
    const key = `${item.city}_${item.country}`;
    if (!groups[key]) {
        groups[key] = { city: item.city, items: [] };
    }
    groups[key].items.push(item);
}
// 将分组对象的值转为数组,得到最终结构
const grouped = Object.values(groups);

console.log(grouped);

说明

  • 两种方法均通过city与country的拼接字符串确保分组唯一性;
  • 最终用Object.values()将分组对象转换为你需要的数组格式;
  • 修正了目标结构中的笔误,统一使用items字段。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 07:15:32