【问题标题】:mergeWith for [Object]为 [对象] 合并
【发布时间】:2017-01-01 00:35:57
【问题描述】:

是否有任何推荐的方法或功能将 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与前一个和当前对象合并的方法。

有什么想法可以用函数库以简洁、纯粹的方式做到这一点吗?我更喜欢 Ramda,但任何事情都会很棒。

【问题讨论】:

    标签: functional-programming lodash ramda.js


    【解决方案1】:

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

    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;
        });
      }
    }
    

    【讨论】:

    • 这将是一个更好的答案,如果您 a) 添加解释 b) 警告递归,这不是很明显,因为 c) 您不幸使用单字母变量名,甚至隐藏其中一些在内部函数中。
    • 谢谢!抱歉回滚您的编辑。现在我已经说得更清楚了,因为它是在 FP 库的上下文中被问到的。特别是拉姆达。暂时在这里投票。
    • @JaredSmith 我认为我的代码是如何工作的很明显,但没关系,我更新了我的答案。
    • @jiku 为什么在纯 JavaScript 中更容易使用 Ramda?另外,我认为这是最短的解决方案,因为没有 Ramda 库可以完全满足您的需求。
    • @SoftwareEngineer171 主要是为了学习和使用 FP 和 Ramda。我希望它可以在几行内完成,而不会变得不清楚。
    【解决方案2】:

    Ramda 目前没有 mergeDeepmergeDeepWith 函数。但它可能很快就会被添加。见PR 1867

    有了这些,你就可以简单地做

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

    您可以在 REPL 中看到模拟情况。

    (您需要使用add 而不是sum,因为reduce 表示一次处理一对对象。add 用于两个数字,sum 用于它们的列表。)

    【讨论】:

    • 太好了!非常感谢分享实现。我会从中学到很多东西。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-09
    • 1970-01-01
    • 2021-12-18
    • 2021-07-28
    • 2015-11-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多