我试图使用Lodash's merge找到与Ramda等效的函数,该pull request执行基于关键字的递归对象" merge"或者"延伸"。行为类似于以下内容:
let merged = R.someMethod(
{ name: 'Matt', address: { street: 'Hawthorne', number: 22, suffix: 'Ave' }},
{ address: { street: 'Pine', number: 33 }}
);
console.log(merged);
// => { name: 'Matt', address: { street: 'Pine', number: 33, suffix: 'Ave' }}
我注意到以下rolled back中简要介绍了R.set
,但之后不久{{3}}。从那以后,Ramda库是否已捕获此功能?
Ramda中是否提供此功能?
答案 0 :(得分:6)
可以使用R.mergeWith
创建一个相对简单的递归函数。
function deepMerge(a, b) {
return (R.is(Object, a) && R.is(Object, b)) ? R.mergeWith(deepMerge, a, b) : b;
}
deepMerge({ name: 'Matt', address: { street: 'Hawthorne', number: 22, suffix: 'Ave' }},
{ address: { street: 'Pine', number: 33 }});
//=> {"address": {"number": 33, "street": "Pine", "suffix": "Ave"}, "name": "Matt"}
答案 1 :(得分:5)
Ramda目前不包括这样的功能。
有几次尝试创造一个,但他们似乎建立了这种功能真正需要的概念。
如果您认为值得添加,请随意raise an issue。
(两年后。)这最终以几个函数的形式添加:mergeDeepLeft
,mergeDeepRight
,mergeDeepWith
和mergeDeepWithKey
。
答案 2 :(得分:1)
Ramda现在有几个合并功能:mergeDeepLeft,mergeDeepRight,mergeDeepWith,mergeDeepWithKey。
答案 3 :(得分:0)
const { unapply, mergeDeepRight, reduce } = R
const mergeDeepRightAll = unapply(reduce(mergeDeepRight, {}))
console.log(mergeDeepRightAll({a:1, b: {c: 1}},{a:2, d: {f: 2}},{a:3, b: {c:3}}))
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
答案 4 :(得分:0)
从头开始
Ramba库中的新功能意味着您不必自己执行此操作,但是如果维护者从不执行此操作怎么办?当您现在需要某种功能或行为时,您不想被困在等待别人编写代码。
下面,我们实现了自己的递归merge
const isObject = x =>
Object (x) === x
const merge = (left = {}, right = {}) =>
Object.entries (right)
.reduce
( (acc, [ k, v ]) =>
isObject (v) && isObject (left [k])
? { ...acc, [k]: merge (left [k], v) }
: { ...acc, [k]: v }
, left
)
我们的合并功能也可以正常工作,并且接受任何两个对象作为输入。
const x =
{ a: 1, b: 1, c: 1 }
const y =
{ b: 2, d: 2 }
console.log (merge (x, y))
// { a: 1, b: 2, c: 1, d: 2 }
如果每个对象都包含一个属性,该属性的值也是一个对象,则merge将再次发生并合并嵌套的对象。
const x =
{ a: { b: { c: 1, d: 1 } } }
const y =
{ a: { b: { c: 2, e: 2 } }, f: 2 }
console.log (merge (x, y))
// { a: { b: { c: 2, d: 1, e: 2 } }, f: 2 }
数组也是人
为了支持merge
中的数组,我们引入了一个突变帮助器mut
,该助手将[ key, value ]
对分配给给定的对象o
。数组也被视为对象,因此我们可以使用相同的mut
函数来更新数组和对象
请注意,Ramda的合并功能不会尝试合并数组。编写自己的函数的主要优点是,您可以轻松地增强其行为,以满足程序不断发展的要求。
const mut = (o, [ k, v ]) =>
(o [k] = v, o)
const merge = (left = {}, right = {}) =>
Object.entries (right)
.map
( ([ k, v ]) =>
isObject (v) && isObject (left [k])
? [ k, merge (left [k], v) ]
: [ k, v ]
)
.reduce (mut, left)
按预期进行浅层合并
const x =
[ 1, 2, 3, 4, 5 ]
const y =
[ 0, 0, 0 ]
const z =
[ , , , , , 6 ]
console.log (merge (x, y))
// [ 0, 0, 0, 4, 5 ]
console.log (merge (y, z))
// [ 0, 0, 0, <2 empty items>, 6 ]
console.log (merge (x, z))
// [ 1, 2, 3, 4, 5, 6 ]
也可以进行深度合并
const x =
{ a: [ { b: 1 }, { c: 1 } ] }
const y =
{ a: [ { d: 2 }, { c: 2 }, { e: 2 } ] }
console.log (merge (x, y))
// { a: [ { b: 1, d: 2 }, { c: 2 }, { e: 2 } ] }
可变合并
也许我们想要一个不限于两个输入的合并功能; mergeAll
const Empty =
{}
const mergeAll = (first = Empty, ...rest) =>
first === Empty
? first
: merge (first, mergeAll (...rest))
mergeAll ({ a: 1 }, { b: 2 }, { c: 3 })
// { a: 1, b: 2, c: 3 }
此答案是另一个问题的摘录:How to compare two objects and get key-value pairs of their differences?