如何将对象数组简化为一个对象?

问题描述

我开始使用reduce,并且很难理解如何使用它。在使用数字时,我理解它,但是在涉及对象和其他数据时,我很难遵循逻辑。我想获取一个对象数组,并返回一个带有countryName键的对象,该值是带有其他国家/地区数据的对象。任何帮助将不胜感激!

数据

var countries = [
  {
    "countryCode": "AF","countryName": "Afghanistan","population": "29121286","capital": "Kabul","continentName": "Asia"
  },{
    "countryCode": "AL","countryName": "Albania","population": "2986952","capital": "Tirana","continentName": "Europe"
  },{
    "countryCode": "DZ","countryName": "Algeria","population": "34586184","capital": "Algiers","continentName": "Africa"
  },]

预期产量

{
  Afghanistan: {
    "countryCode": "AF",Albania: {
    "countryCode": "AL",Algeria: {
    "countryCode": "DZ",}

基本尝试

function organizeByCountry(countries) {
  return countries.reduce((acc,country) => {

    return country.countryName 
  },{})
}

解决方法

您可以使用Array.map()创建[国家/对象]对的数组,并使用Object.fromEntries()将其转换为对象:

const keyByWithoutKey = (arr,key) => Object.fromEntries(
  arr.map(({ [key]: prop,...o }) => [prop,o])
)

const countries =  [{"countryCode":"AF","countryName":"Afghanistan","population":"29121286","capital":"Kabul","continentName":"Asia"},{"countryCode":"AL","countryName":"Albania","population":"2986952","capital":"Tirana","continentName":"Europe"},{"countryCode":"DZ","countryName":"Algeria","population":"34586184","capital":"Algiers","continentName":"Africa"}]

const result = keyByWithoutKey(countries,'countryName')

console.log(result)

,

Array.prototype.reduce在其典型用法中可以可视化为一个函数,该函数一次逐步构建输出一个列表条目,从第一个列表条目和您作为第二个参数提供的累加器开始( {})。

reduce为每个列表项调用回调(除非您不传递累加器,否则您可以在MDN上阅读更多内容)。在您的情况下,第一次调用时,回调将收到如下参数:

acc = {};
country = {
  countryCode: "AF",countryName: "Afghanistan",population: "29121286",capital: "Kabul",continentName: "Asia"
};

我们现在开始构建结果。我们想要一个对象,该对象具有键作为国家名称,值具有作为对象中其余属性的值。我们正是通过修改累加器来构建的:

acc[country.countryName] = {
  countryCode: country.countryCode,population: country.population,capital: country.capital,continentName: country.continentName
};

然后,我们从回调中返回此修改后的累加器。在reduce的下一次回调调用中,回调将先前返回的累加器作为acc参数,并将第二个列表项作为country

acc = {
  Afghanistan: {
    countryCode: "AF",continentName: "Asia"
  }
};
country = {
  countryCode: "AL",countryName: "Albania",population: "2986952",capital: "Tirana",continentName: "Europe"
};

这时,我们重复并返回修改后的累加器。在reduce最后一次使用更新的累加器和列表中的最后一项调用回调之后,回调返回的值由reduce函数本身返回。因此,我们现在使用reduce获得输出。


上述逻辑可以简明地实现如下,同时还避免了变异:

function organizeByCountry(countries) {
  return countries.reduce((acc,country) => {
    const {countryName,...rest} = country;

    return {...acc,[countryName]: rest};
  },{});
};