【问题标题】:How to merge/concatenate values of same object properties in an array of objects using lodash?如何使用lodash合并/连接对象数组中相同对象属性的值?
【发布时间】:2019-05-30 05:47:39
【问题描述】:

我有一个对象数组,如下所示:

let fruitSamples = [
  [
    {'id': 1,'type': 'apples','samples': [1, 2, 3]},
    {'id': 2,'type': 'bananas','samples': [1, 2, 7]},
    {'id': 3,'type': 'pears','samples': [1, 2, 3]}
  ],
  [
    {'id': 1,'type': 'apples','samples': [5, 2, 9]},
    {'id': 2,'type': 'bananas','samples': [1, 7, 7]},
    {'id': 3,'type': 'pears','samples': [12, 21, 32]}
  ],
  [
    {'id': 1,'type': 'apples','samples': [11, 2, 33]},
    {'id': 2,'type': 'bananas','samples': [17, 2, 67]},
    {'id': 3,'type': 'pears','samples': [91, 22, 34]}
  ]
];

我想使用 lodash 将上述数组减少并合并为一个,以便样本像这样连接在一起:

fruitSamples = [
  {'id': 1, 'type': 'apples', 'samples': [1,2,3,5,2,9,11,2,33]},
  {'id': 2, 'type': 'bananas', 'samples': [1,2,7,1,7,7,17,2,67]},
  {'id': 3, 'type': 'pears', 'samples': [1,2,3,12,21,32,91,22,34]},
]

我尝试了许多不同的方法,但由于我想要解决此问题的最短方法,您的建议是什么?

我试过这个:

let test = _(fruitSamples)
  .flatten()
  .groupBy('type')
  .map(_.spread(_.merge))
  .value();

console.log(test);

这给了我以下结果,它不会连接样本:

test = [
  {'id': 1,'type': 'apples','samples': [11, 2, 33]},
  {'id': 2,'type': 'bananas','samples': [17, 2, 67]},
  {'id': 3,'type': 'pears','samples': [91, 22, 34]}
]

我觉得使用 _.mergeWith 可能是正确的答案,如果是这样,我正在寻求以最佳方式实施 mergeWith 的帮助,因为我不知道该怎么做。有什么建议吗?

【问题讨论】:

    标签: javascript arrays lodash javascript-objects


    【解决方案1】:

    您可以尝试使用接受customizer 函数的_.mergeWith 而不是_.merge,您可以使用该函数自定义分配的值。

    来自official docs

    这个方法类似于_.merge,除了它接受定制器,它是 调用以生成目标和源的合并值 特性。

    let fruitSamples = [
      [
        {'id': 1,'type': 'apples','samples': [1, 2, 3]},
        {'id': 2,'type': 'bananas','samples': [1, 2, 7]},
        {'id': 3,'type': 'pears','samples': [1, 2, 3]}
      ],
      [
        {'id': 1,'type': 'apples','samples': [5, 2, 9]},
        {'id': 2,'type': 'bananas','samples': [1, 7, 7]},
        {'id': 3,'type': 'pears','samples': [12, 21, 32]}
      ],
      [
        {'id': 1,'type': 'apples','samples': [11, 2, 33]},
        {'id': 2,'type': 'bananas','samples': [17, 2, 67]},
        {'id': 3,'type': 'pears','samples': [91, 22, 34]}
      ]
    ];
    
    function customizer(objValue, srcValue) {
      if (_.isArray(objValue)) {
        return objValue.concat(srcValue);
      }
    }
    
    let test = _(fruitSamples)
      .flatten()
      .groupBy('type')
      .map(_.spread((...values) => {
        return _.mergeWith(...values, customizer);
      }))
      .value();
      
    console.log(test);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

    【讨论】:

    • 尽管我使用了 no-lodash 答案,但这有助于我理解 mergeWith 函数。谢谢。
    【解决方案2】:

    不知道如何使用 lodash,但是纯 Javascript 并不太难。

    更新:感谢@Taki 做了一个flat() 首先使这变得更平 更容易..

    let fruitSamples = [[{"id":1,"type":"apples","samples":[1,2,3]},{"id":2,"type":"bananas","samples":[1,2,7]},{"id":3,"type":"pears","samples":[1,2,3]}],[{"id":1,"type":"apples","samples":[5,2,9]},{"id":2,"type":"bananas","samples":[1,7,7]},{"id":3,"type":"pears","samples":[12,21,32]}],[{"id":1,"type":"apples","samples":[11,2,33]},{"id":2,"type":"bananas","samples":[17,2,67]},{"id":3,"type":"pears","samples":[91,22,34]}]];
    
    let concat = fruitSamples.flat().reduce((a, i) => {
      const f = a.find(f => f.id === i.id);
      if (!f) a.push(i);
      else f.samples = [...f.samples, ...i.samples];
      return a;
    }, []);
    
    console.log(concat);

    【讨论】:

    • 如果你使用fruitSamples.flat().reduce(),你可以避免嵌套循环
    • 工作起来就像一个魅力,虽然我相信 flat() 方法在旧版本的 chrome 和其他一些浏览器中不起作用(我还没有测试过它们),所以我会坚持使用 forEach现在。干杯。
    • @Daybreak 没问题,。我给出的任何答案我总是尝试使用现代 Javascript 技术,我喜欢前进而不是倒退。使用 polyfill 和转译器是创建优秀 Web 应用程序的标准方法,没有理由不这样做:)
    【解决方案3】:

    您可以先使用.reduce 将一个或多个数组转换为简单数组,然后再次使用.reduce 进行分组。

    可能更容易抓住

    类似

    let fruitSamples = [
      [
        {'id': 1,'type': 'apples','samples': [1, 2, 3]},
        {'id': 2,'type': 'bananas','samples': [1, 2, 7]},
        {'id': 3,'type': 'pears','samples': [1, 2, 3]}
      ],
      [
        {'id': 1,'type': 'apples','samples': [5, 2, 9]},
        {'id': 2,'type': 'bananas','samples': [1, 7, 7]},
        {'id': 3,'type': 'pears','samples': [12, 21, 32]}
      ],
      [
        {'id': 1,'type': 'apples','samples': [11, 2, 33]},
        {'id': 2,'type': 'bananas','samples': [17, 2, 67]},
        {'id': 3,'type': 'pears','samples': [91, 22, 34]}
      ]
    ];
    
    var merged = fruitSamples.reduce(function(prev, next) {
      return prev.concat(next);
    });
    
    var res = merged.reduce(function(prev, next) {
          
          var index = prev.findIndex(o=> o.id == next.id) 
             if(index >= 0)
               prev[index].samples = [...prev[index].samples,...next.samples];
               else
               prev.push(next);
               
               return prev;
    },[]);
    
    console.log(res)

    【讨论】:

      【解决方案4】:

      一种使用 javascript 而没有 lodash 的方法:

      var fruitSamples = [
      [
         {'id': 1,'type': 'apples','samples': [1, 2, 3]},
         {'id': 2,'type': 'bananas','samples': [1, 2, 7]},
         {'id': 3,'type': 'pears','samples': [1, 2, 3]}
      ],
      [
         {'id': 1,'type': 'apples','samples': [5, 2, 9]},
         {'id': 2,'type': 'bananas','samples': [1, 7, 7]},
         {'id': 3,'type': 'pears','samples': [12, 21, 32]}
      ],
      [
         {'id': 1,'type': 'apples','samples': [11, 2, 33]},
         {'id': 2,'type': 'bananas','samples': [17, 2, 67]},
         {'id': 3,'type': 'pears','samples': [91, 22, 34]}
       ]
       ];
      
      var test = fruitSamples.flat().reduce((rv,x)=>{
        var f = rv.find(y => y.id == x.id);
        if(f == null){
              f ={"id":x.id, "type":x.type,"samples":x.samples};
              rv.push(f);
        }
        else{
           f.samples = f.samples.concat(x.samples);
        }
        return rv;
      },[]);
      console.log(JSON.stringify(test))
      

      https://jsfiddle.net/pimboden40/y8x96sbg/1/

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-12-31
        • 1970-01-01
        • 2016-04-20
        • 1970-01-01
        • 1970-01-01
        • 2017-12-12
        • 2022-08-17
        • 2020-02-08
        相关资源
        最近更新 更多