mergeWith [Object]

时间:2016-08-24 18:35:38

标签: functional-programming lodash ramda.js

是否有任何推荐的方法或功能将R.mergeWith的fn功能与n个列表项结合起来,如R.mergeAll?

我有

const data = [
  { a: 1, b: 2, c: 0, d: { e: 3 }},
  { a: 1, c: -1 },
  { a: 1, b: 4, c: 0, d: { e: 2 }}
]

并希望按键对所有值求和,返回

{ a: 3, b: 6, c: -1, d: { e: 5 }}

我尝试过像

这样的东西
R.mapAccum((a, b) => R.mergeWith(R.sum, a, b), {}, data)

(在REPL中)猜测我所追求的是通过一些fn合并前一个和当前对象的方法。

我是如何以简洁,纯粹的方式使用功能库来实现这一目标的?我更喜欢拉姆达,但任何事情都会很棒。

2 个答案:

答案 0 :(得分:2)

假设您的对象中没有循环结构,这将解决您的问题。

function merge(array){
  // Returns merged array
  return mergeSubArray(array);

  // This function recursively process all sub-arrays
  function mergeSubArray(subArray){

    // Sum all properties of all objects in the array
    return subArray.reduce(function(previousObject, currentObject){

      // Get all properties of an object
      Object.keys(currentObject).forEach(function(keyOfCurrentObject){
        /*
          For all properties we need to check whether this type if number or object.
          If we encountered a number, we simply add it to previous sum.
          Otherwise, if it is an object, call this function to it.
        */

        if(typeof previousObject[keyOfCurrentObject] == 'number'){
          previousObject[keyOfCurrentObject] += currentObject[keyOfCurrentObject];
        }else{
          previousObject[keyOfCurrentObject] = mergeSubArray([previousObject[keyOfCurrentObject], currentObject[keyOfCurrentObject]]);
        }
      });

      // Returns merged objects
      return previousObject;
    });
  }
}

答案 1 :(得分:1)

Ramda目前没有mergeDeepmergeDeepWith功能。但它很快就会被加入。请参阅PR 1867

有了这个,你可以简单地做

R.reduce(R.mergeDeepWith(R.add), {}, data)

您可以在 REPL 中看到模拟结果。

(您需要使用add而不是sum,因为reduce表示一次使用一对对象。add代表两个数字{{1}它是一个列表。)