代码之家  ›  专栏  ›  技术社区  ›  Daniel Santos

使用lodash按键自定义求和元素

  •  1
  • Daniel Santos  · 技术社区  · 6 年前

    我有两个包含键的对象

    var a = {bar:[1,2], foo:[7,9]}
    var b = {bar:[2,2], foo:[3,1]}
    

    我想得到放松的结果:

    var c = {bar:[3,4], foo:[10,10]}
    

    我已经有了 for 逻辑如下:

    for (let key in b) {
      if (a[key]) {
          a[key][0] += b[key][0];
          a[key][1] += b[key][1];
      } 
      else a[key] = b[key];
    }
    

    但我想用罗达什的方式来解释这个逻辑。我该怎么做?

    2 回复  |  直到 6 年前
        1
  •  1
  •   Ori Drori    6 年前

    您可以使用创建一个函数 n 对象,并使用 rest parameters . 现在你可以 spread 数组进入 _.mergeWith() 要组合对象,在customizer函数中,使用 Array.map() 或土卫十六 _.map() _.add() :

    const { mergeWith, isArray, map, add } = _
    
    const fn = (...rest) => _.mergeWith({}, ...rest, (o = [], s) =>
      map(s, (n, i) => add(n, o[i]))
    )
    
    const a = {bar:[1,2], foo:[7,9]}
    const b = {bar:[2,2], foo:[3,1]}
    const c = {bar:[3,2], foo:[5,6]}
    const d = {bar:[4,2], foo:[5,4]}
    
    const result = fn(a, b, c, d)
    
    console.log(result)
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

    您也可以使用 lodash/fp 创建将所有值合并到多维数组的函数 _.mergeAllWith() ,然后使用 _.zipAll() ,并对每个数组求和:

    const { rest, flow, mergeAllWith, isArray, head, mapValues, zipAll, map, sum } = _
    
    const fn = rest(flow(
      mergeAllWith((o, s) => [...isArray(head(o)) ? o : [o], s]), // combine to a multidimensional array
      mapValues(flow(
        zipAll,
        map(sum)
      )),
    ))
    
    const a = {bar:[1,2], foo:[7,9]}
    const b = {bar:[2,2], foo:[3,1]}
    const c = {bar:[3,2], foo:[5,6]}
    const d = {bar:[4,2], foo:[5,4]}
    
    const result = fn(a, b, c, d)
    
    console.log(result)
    <script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>
        2
  •  1
  •   jo_va    6 年前

    您可以使用纯JavaScript Object.entries , concat reduce :

    const a = { bar: [1,2], foo: [7,9] };
    const b = { bar: [2,2], foo: [3,1] };
    
    const entries = Object.entries(a).concat(Object.entries(b));
    
    const result = entries.reduce((accum, [key, val]) => {
      accum[key] = accum[key] ? accum[key].map((x, i) => x + val[i]) : val;
      return accum;
    }, { });
    
    console.log(result);