使用Lodash,如何将此数据转换为所需格式?

时间:2016-06-09 23:51:11

标签: javascript lodash

我对lodash相当新,并怀疑它可以帮助我以我想要的方式转换数据。我一直在阅读lodash docs,但说实话,它并没有下沉,我没有看到我需要的正确操作组合。

这是我想要做的:

var configs = [ { 
      configId: 1,
      options: [ {categoryId: 1, id: 100},
                 {categoryId: 2, id: 200},
                 {categoryId: 3, id: 300} ] },
    { 
      configId: 2,
      options: [ {categoryId: 1, id: 105},
                 {categoryId: 2, id: 210} ] },
    { 
      configId: 3,
      options: [ {categoryId: 2, id: 200},
                 {categoryId: 1, id: 165},
                 {categoryId: 3, id: 300} ] }
];

//  I want the above to look like this:
/*
[ {categoryId: 1, ids: [100, 105, 165]},
  {categoryId: 2, ids: [200, 210]},
  {categoryId: 3, ids: [300]} ]
*/

如果你想进行实验,这里是fiddle

当我看到问题时,我想我想:

  1. 合并所有configs个对象,这样我就有了一大堆options个对象
  2. 分组categoryId
  3. 然后我真的迷失了方向......我怀疑我可以在这里使用reduce(),但是我还认为我需要一个map()来实际生成转换后的对象。
  4. 无论如何,我在这方面没有取得进展,我希望有人能指出正确的方向。

2 个答案:

答案 0 :(得分:2)

使用ES2015语法:

_.map(
  _.groupBy(_.flatMap(configs, config => config.options), 'categoryId'), 
  (val, key) => ({categoryId: key, ids: _.uniq(_.map(val, v => v.id)) })
)

兼容ES5(由Babel生成):

_.map(
  _.groupBy(
    _.flatMap(configs, function (config) {
    return config.options;
    }), 
  'categoryId'), 
  function (val, key) {
    return {
        categoryId: key,
        ids: _.uniq(_.map(val, function (v) {
            return v.id;
        }))
    };
});

说明:

_.flatMap(configs, config => config.options)

从每个configs对象中获取options数组,将它们展平为[{categoryId: xx, id: yy}, ...]

的单个数组
[ {categoryId:1,id:100},
  {categoryId:2,id:200},
  {categoryId:3,id:300},
  {categoryId:1,id:105},
  {categoryId:2,id:210},
  {categoryId:2,id:200},
  {categoryId:1,id:165},
  {categoryId:3,id:300} ]


_.groupBy(..., 'categoryId')

数组上方的categoryId[{xx: [categoryId: xx, id: yy}, ...]

{
    1:[
        {categoryId:1,id:100},
        {categoryId:1,id:105},
        {categoryId:1,id:165} ],
    2:[
        {categoryId:2,id:210},
        {categoryId:2,id:200},
        {categoryId:2,id:200} ],
    3:[
        {categoryId:3,id:300},
        {categoryId:3,id:300} ] }

_.map(..., (val, key) => ({categoryId: key, ids: _.uniq(_.map(val, v => v.id)) }))

接收val = [{xx: [categoryId: xx, id: yy}, ...]key: xx并将其映射到categoryId设置为已接收密钥的对象,并将ids映射到来自分组的唯一id数组对象。结果是您想要的数组。

[ {
    categoryId:1,
    ids:[100,105,165]},
  {
    categoryId:2,
    ids:[200,210]},
  {
    categoryId:3,
    ids:[300]}]

答案 1 :(得分:1)



var configs = [{
  configId: 1,
  options: [
    {categoryId: 1, id: 100},
    {categoryId: 2, id: 200},
    {categoryId: 3, id: 300} 
  ]
}, { 
  configId: 2,
  options: [
    {categoryId: 1, id: 105},
    {categoryId: 2, id: 210}
  ]
}, { 
  configId: 3,
  options: [
    {categoryId: 2, id: 200},
    {categoryId: 1, id: 165},
    {categoryId: 3, id: 300}
  ]
}];

var result = _.chain(configs)
  .flatMap(config => config.options)
  .groupBy(id => id.categoryId)
  .map((list, categoryId) => ({
    categoryId: +categoryId,
    ids: _.chain(list)
      .map(x => x.id)
      .uniq()
      .value()
  }))
  .value();

document.body.textContent = JSON.stringify(result,null,2);

body {
  white-space: pre-wrap;
}

<script src="https://cdn.jsdelivr.net/lodash/4.13.1/lodash.js"></script>
&#13;
&#13;
&#13;