使用 reduce属性未定义转换数组

问题描述

我想将数组转换为重新组合同一国家/地区的所有城市。 我有一个对象数组

filesize("audio/$file")

我想要这个:

locations = [
{
cities: ["Paris"]
country: "France"
},{
cities: ["Marseille"]
country: "France"
},{
cities: ["Kiev"]
country: "Ukraine"
},{
cities: ["Odessa"]
country: "Ukraine"
}
...

所以,我的想法是:

locations = [
{
cities: ["Paris","Marseille"]
country: "France"
},{
cities: ["Kiev,Odessa"]
country: "Ukraine"
},...

对于第一对相等的国家,curr.cities[0] 被推送到 prev.cities,但不是下一次迭代: 类型错误:无法读取未定义的属性“国家/地区”

[![console.log(locations) - TypeError: 无法读取未定义的属性 'country'][1]][1]

解决方法

使用reduce时,需要返回prev以供下次迭代使用,并且初始化为{}。此外,您需要注意每个国家/地区的初始添加,其中应存储具有 cities 数组的对象:

const locations = [
  { country: "France",cities: ['city1','city2'] },{ country: "France",cities: ['city3','city4'] },{ country: "Ukraine",cities: ['city5'] },cities: ['city6'] }
];

const res = Object.values(locations.reduce((prev,curr) => {
  const { country,cities = [] } = curr;
  const [city] = cities;
  if (prev[country] && city) {
    prev[country].cities.push(city);
  } else {
    prev[country] = { country,cities: city ? [city] : [] };
  }
  return prev;
},{}));

console.log(res);

,

您可以创建一个以国家/地区为键的 Map,并使用一个初始为空的数组作为相应的值。然后填充这些数组,最后从该 Map 中提取条目。这具有线性时间复杂度:

let locations = [{cities: ["Paris"],country: "France"},{cities: ["Marseille"],{cities: ["Kiev"],country: "Ukraine"},{cities: ["Odesa"],country: "Ukraine"}];

let map = new Map(locations.map(({country}) => [country,{country,cities: []}]));
for (let loc of locations) map.get(loc.country).cities.push(...loc.cities);
let res = Array.from(map.values());

console.log(res);

,

我认为要获得所需的输出格式,您可以执行以下操作:

locations = [
  { cities: ["Paris"],country: "France" },{ cities: ["Marseille"],{ cities: ["Kiev"],country: "Ukraine" },{ cities: ["Odesa"],country: "Ukraine" }
];

var grouped = Object.entries(
  locations.reduce((a,cities}) => ({
    ...a,[country]: [...(a[country] || []),...cities]
  }),{})
).map(([country,cities]) => ({ country: country,cities: cities }),[]);
  
console.log(grouped);