简化和排序从现有阵列中创建新阵列的过程

时间:2019-01-20 10:52:35

标签: javascript arrays sorting ecmascript-6

我有一个这样的对象数组:

[
   {country: 'a', region: 1}
   {country: 'a', region: 2}
   {country: 'a', region: 3}
   {country: 'b', region: 4}
   {country: 'b', region: 5}
   {country: 'c', region: 6}
   {country: 'd', region: 7}
   {country: 'e', region: 8}
]

我想结束一个像这样的数组:

[
   {country: 'a', region: [1, 2, 3]}
   {country: 'b', region: [4, 5]}
   {country: 'c', region: [6]}
   {country: 'd', region: [7]}
   {country: 'e', region: [8]}
]

我一直在尝试以下操作,但是我被困在想要将结果推送到现有byCountry数组中的部分...

我还觉得filter可能不是最好的功能,它可能比我写的要复杂得多。

 let byCountry = []

    regions.forEach( (region) => {
      const filter = byCountry.filter( country => country.country === region.country )

      if (filter.length > 0) {
        const filteredCountry = filter[0]['country']
        const result = _.find(byCountry, country => {
          return country.country === filteredCountry
        })
// stuck here

      } else {
        const newCountry = {
          country: region.country,
          regions: [region.region],
        }

        byCountry.push(newCountry)
      }
    })

3 个答案:

答案 0 :(得分:2)

您可以像这样使用reduceObject.values

目标是创建一个对象,每个country值作为键,{country: 'a', region: []}作为值。然后只需使用Object.values来获取输出。

const regions=[{country:'a',region:1},{country:'a',region:2},{country:'a',region:3},{country:'b',region:4},{country:'b',region:5},{country:'c',region:6},{country:'d',region:7},{country:'e',region:8}]

const merged = regions.reduce((acc, {country,region}) => 
  ((acc[country] = acc[country] || {country, region: []}).region.push(region), acc)
, {})

console.log(Object.values(merged))

以下是上述代码的简化版本:

const regions = [{country:'a',region:1},{country:'a',region:2},{country:'a',region:3},{country:'b',region:4},{country:'b',region:5},{country:'c',region:6},{country:'d',region:7},{country:'e',region:8}]

const merged = regions.reduce((acc, {country,region}) => {
  acc[country] = acc[country] || {country, region: []};
  acc[country].region.push(region);
  return acc;
}, {})

console.log(Object.values(merged))

答案 1 :(得分:1)

您只需将数组转换为哈希图即可将国家/地区映射到多个地区{<country>: Array<regions>},然后再将其转换回数组:

const records = [
      {country: 'a', region: 1},
      {country: 'a', region: 2},
      {country: 'a', region: 3},
      {country: 'b', region: 4},
      {country: 'b', region: 5},
      {country: 'c', region: 6},
      {country: 'd', region: 7},
      {country: 'e', region: 8}
    ];

const regionsByCountry = new Map();

records.forEach(record => {
  if (!regionsByCountry.has(record.country)) {
    regionsByCountry.set(record.country, []);
  }

  regionsByCountry.get(record.country).push(record.region);
});

const merged = Array.from(regionsByCountry)
                    .map(([country, region]) => ({country,region}));
                    
console.log(merged)

您可以使用具有可读API的现代Map或普通对象文字{}

地图文档:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map

答案 2 :(得分:0)

使用Array.reduce()将值收集到Map中,然后使用Array.from()转换回对象:

const data = [{"country":"a","region":1},{"country":"a","region":2},{"country":"a","region":3},{"country":"b","region":4},{"country":"b","region":5},{"country":"c","region":6},{"country":"d","region":7},{"country":"e","region":8}]
  
const result = Array.from(
  data.reduce((m, { country, region }) => 
    m.set(country, [...(m.get(country) || []), region])
  , new Map),
  ([country, region]) => ({ country, region })
)

console.log(result)