最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to reduce array of objects into one object? - Stack Overflow

programmeradmin6浏览0评论

I'm beginning working with reduce and I'm having a hard time conceptualizing how to use it. I understand it when using numbers, but when it es to objects and other data, I have a hard time following the logic. I want to take an array of objects and return an object with the keys of countryName and the value being an object with the rest of the country data. Any help would be greatly appreciated!

Data

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"
  },
]

Expected Output

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

Base Attempt

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

    return country.countryName 
  }, {})
}

I'm beginning working with reduce and I'm having a hard time conceptualizing how to use it. I understand it when using numbers, but when it es to objects and other data, I have a hard time following the logic. I want to take an array of objects and return an object with the keys of countryName and the value being an object with the rest of the country data. Any help would be greatly appreciated!

Data

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"
  },
]

Expected Output

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

Base Attempt

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

    return country.countryName 
  }, {})
}
Share Improve this question asked Oct 3, 2020 at 19:19 mfaccordmfaccord 2251 gold badge4 silver badges15 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 10

Array.prototype.reduce in its typical usage can be visualized as a function that progressively builds your output one list entry at a time, starting with the first list entry and the accumulator you provide as the second argument (In this case, {}).

reduce invokes your callback for every list item (Except when you don't pass an accumulator, you can read more on this on MDN). In the first invocation in your case, the callback receives arguments as below:

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

We now start building the result. We want an object which has keys as the country names and values as the rest of the attributes in the object. We build exactly that, by modifying the accumulator:

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

We then return this modified accumulator from the callback. In the next invocation of the callback by reduce, the callback receives this previously returned accumulator as the acc argument and the second list item as country:

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

At this point, we repeat and return the modified accumulator. After reduce invokes the callback for the last time with the updated accumulator and the last item from the list, the value returned by the callback is returned by the reduce function itself. We thus have our output now, using reduce.


The above logic can be concisely implemented as below, while additionally avoiding mutations:

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

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

let 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 countryName = countries.reduce((acc, country)=>{
        return {...acc, [country.countryName]:country}
    },{})
    
 console.log(countryName)

You can use Array.map() to create an array of [country, object] pairs, and convert it to an object using 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)

发布评论

评论列表(0)

  1. 暂无评论