如何按属性聚合嵌套的JavaScript对象?

时间:2019-03-14 04:52:58

标签: javascript

我有以下JavaScript对象:

var example = [{
    country: "US",
    things: {
      weather: 'cloudy'
    }
  },
  {
    country: "US",
    things: {
      resource: 'lead',
      weather: 'sunny'
    }
  },
  {
    country: "MX",
    things: {
      weather: 'sunny'
    }
  },
  {
    country: "MX",
    things: {
      resource: 'gold',
      weather: 'sunny'
    }
  },
  {
    country: "MX",
    things: {
      resource: 'copper'
    }
  },
]

我想通过汇总转换为这种格式。

var out = [{
    country_code: 'US',
    things: {
      resource: ['lead'],
      weather: ['cloudy', 'sunny']
    }
  },
  {
    country_code: 'MX',
    things: {
      resource: ['gold', 'copper'],
      weather: ['sunny'],
    }
  }

]

我试图研究使用reduce和map的组合都无济于事。如果此示例还可以用作通用数据处理策略的起点,那么可能会或可能不会涉及使用数组方法。

5 个答案:

答案 0 :(得分:2)

使用reduce遍历对象以编译新对象,将所需的内容拼凑在一起:

const example = [{
    country: "US",
    things: {
      weather: 'cloudy'
    }
  },
  {
    country: "US",
    things: {
      resource: 'lead',
      weather: 'sunny'
    }
  },
  {
    country: "MX",
    things: {
      weather: 'sunny'
    }
  },
  {
    country: "MX",
    things: {
      resource: 'gold',
      weather: 'sunny'
    }
  },
  {
    country: "MX",
    things: {
      resource: 'copper'
    }
  },
]

const out = Object.values(
  example.reduce((a, v) => {
    if (!a[v.country]) {
      a[v.country] = {
        country_code: v.country,
        things: {}
      }
    }

    Object.entries(v.things).forEach(([key, value]) => {
      if (!a[v.country].things[key]) {
        a[v.country].things[key] = []
      }

      if (!a[v.country].things[key].includes(value)) {
        a[v.country].things[key].push(value)
      }
    })

    return a
  }, {})
)

console.log(out)

答案 1 :(得分:1)

这将向您展示如何使用reduce来获取要使用reduce的数据

const example = [{
    country: "US",
    things: {
      weather: "cloudy"
    }
  },
  {
    country: "US",
    things: {
      resource: "lead",
      weather: "sunny"
    }
  },
  {
    country: "MX",
    things: {
      weather: "sunny"
    }
  },
  {
    country: "MX",
    things: {
      resource: "gold",
      weather: "sunny"
    }
  },
  {
    country: "MX",
    things: {
      resource: "copper"
    }
  }
];

const output = example.reduce((acc, current) => {
  const index = acc.findIndex(x => x.country === current.country);
  if (index === -1) {
    const newNode = {
      country: current.country,
      things: {
        resource: current.things.resource ? [current.things.resource] : [],
        weather: current.things.weather ? [current.things.weather] : []
      }
    };
    acc.push(newNode);
  } else {
    current.things.resource && acc[index].things.resource.findIndex(x => x === current.things.resource) === -1 && acc[index].things.resource.push(current.things.resource)


    current.things.weather && acc[index].things.weather.findIndex(x => x === current.things.weather) === -1 && acc[index].things.weather.push(current.things.weather)
  }
  return acc;
}, []);

console.log(output);

答案 2 :(得分:1)

可以使用reduce函数并使用findIndex检查累加器是否具有带有country_code的对象。如果存在,则更新things对象中的数组。

var example = [{
    country: "US",
    things: {
      weather: 'cloudy'
    }
  },
  {
    country: "US",
    things: {
      resource: 'lead',
      weather: 'sunny'
    }
  },
  {
    country: "MX",
    things: {
      weather: 'sunny'
    }
  },
  {
    country: "MX",
    things: {
      resource: 'gold',
      weather: 'sunny'
    }
  },
  {
    country: "MX",
    things: {
      resource: 'copper'
    }
  },
]


function finalOut(arr) {
  return arr.reduce(function(acc, curr) {
    let findIndex = acc.findIndex(function(item) {
      return item.country_code === curr.country;
    });
    if (findIndex === -1) {
      acc.push({
        country_code: curr.country,
        things: {
          resource: curr.things.resource ? [curr.things.resource] : [],
          weather: curr.things.weather ? [curr.things.weather] : []
        }
      })
    } else {

      if (curr.things.resource && acc[findIndex].things.resource.indexOf(curr.things.resource) === -1) {
        acc[findIndex].things.resource.push(curr.things.resource);
      }

      if (curr.things.weather && acc[findIndex].things.weather.indexOf(curr.things.weather) === -1) {
        acc[findIndex].things.weather.push(curr.things.weather);
      }

    }

    return acc;
  }, [])
}

console.log(finalOut(example))

答案 3 :(得分:1)

使用reduce可以迭代所有项目,然后以正确的格式排列它们:

example.reduce((prev,current)=>{

        let index = prev.findIndex(item => item.country_code == current.country);

        if(index>=0){
            if(current.things.resource && !prev[index].things.resource.includes(current.things.resource))
                prev[index].things.resource.push(current.things.resource);
            if(current.things.weather && !prev[index].things.weather.includes(current.things.weather))
                prev[index].things.weather.push(current.things.weather);
        }else{
            prev.push({
                country_code : current.country,
                things : {
                    weather : current.things.weather ? [current.things.weather] : [],
                    resource : current.things.resource ? [current.things.resource] : []
                }
            });
        }
        return prev;
},[]);

答案 4 :(得分:1)

  1. 使用reduce
  2. 建立国家/地区数据地图
        $misyukkos = $misyukko1->merge($misyukko2)->toArray();

        $data = array();
        $currentPage = LengthAwarePaginator::resolveCurrentPage();
        $collection = new Collection($misyukkos);
        $per_page = 5;
        $currentPageResults = $collection->slice(($currentPage-1) * $per_page, $per_page)->all();
        $data['results'] = new LengthAwarePaginator($currentPageResults, count($collection), $per_page);
        $data['results']->setPath($request->url());
        dd($data);
  1. 使用Object.entries从地图中获取条目数组
{
  US: {
    resource: ['lead'],
    weather: ['cloudy', 'sunny'],
  },
  MX: {
    resource: ['gold', 'copper'],
    weather: ['sunny'],
  },
}
  1. 将条目数组映射到具有所需结构的对象数组

[
  [ 'US', { resource: ['lead'], weather: ['cloudy', 'sunny'] } ],
  [ 'MX', { resource: ['gold', 'copper'], weather: ['sunny'] } ],
]