Lodash 通过键查找和合并,同时保留特定键值
Lodash find by key and mergeWith while preserving specific key value
我有 2 个 collection,“parent”和“child”collection。
我需要:
通过 ctaTypeNameUID
在 parent 中找到 child 项
如果 child object 值是 parent object 应该被 child object 覆盖不为空。
保持child
的顺序
仅保留 child 中存在的 parent 项 + 来自 child
的自定义项
Parent Object
"parentObjectOverrideable": [{
"cta_type": {
"title": null,
"ctaTypeNameUID": "enjoy-new-york",
"form-url": "F-2009",
"city": "New York",
"address": null
}
},
{
"cta_type": {
"title": null,
"ctaTypeNameUID": "enjoy-london",
"form-url": "F-2010",
"city": "London",
"address": null
}
}
]
Child Object
"childObject": [{
"cta_type": {
"title": "Enjoy London",
"ctaTypeNameUID": "enjoy-london",
"form-url": "F-2009",
"city": null,
"address": null
}
},
{
"cta_type": {
"title": "Enjoy New York",
"ctaTypeNameUID": "enjoy-new-york",
"form-url": "F-22827166628",
"city": null,
"address": null
}
},
]
我试过使用 Lodash 的 _mergeWith
const result = _.mergeWith([], parentObjectOverrideable, childObject, (a, b) =>
b === null || b === '' ? a : undefined
)
问题是,如果 cta_type 在 child object 上的位置不同,它也会覆盖 UID,所以你会得到这样的东西:
"parentObjectOverrideable": [{
"cta_type": {
"title": "Enjoy London",
,
"ctaTypeNameUID": "enjoy-new-york",
"form-url": "F-2009"
"city": null "address": null
}
},
{
"cta_type": {
"title": "Enjoy New York",
"ctaTypeNameUID": "enjoy-london",
"form-url": "F-2010",
"city": null,
"address": null
}
}
]
我也试过这样做
const overrideObject = (objA, objB) => {
const newObject = { ...objB
}
Object.keys(objA).forEach((key) => {
if (objA[key]) {
newObject[key] = objA[key]
}
})
console.log(newObject)
}
知道怎么做吗?
将项目连接到单个数组,将其分组 cta_type.ctaTypeNameUID
,然后将每个组合并到单个对象,让 _.mergeBy()
处理对象和数组的合并,并使用 [= 处理原语16=] 除非它是 null
,而 b
不是 undefined
。
const { flow, concat, groupBy, flatMap, mergeWith, isObject, isUndefined, isNull, intersectionBy } = _
const fn = flow(
concat,
arr => groupBy(arr, 'cta_type.ctaTypeNameUID'),
groups => flatMap(groups, group => mergeWith({}, ...group, (a, b, k) => {
if(isObject(a) || isObject(b)) return undefined
return !isUndefined(b) && isNull(a) ? b : a
})),
)
const parentObjectOverrideable = [{"cta_type":{"title":null,"ctaTypeNameUID":"enjoy-new-york","form-url":"F-2009","city":"New York","address":null}},{"cta_type":{"title":null,"ctaTypeNameUID":"enjoy-london","form-url":"F-2010","city":"London","address":null}}]
const childObject = [{"cta_type":{"title":"Enjoy London","ctaTypeNameUID":"enjoy-london","form-url":"F-2009","city":null,"address":null}},{"cta_type":{"title":"Enjoy New York","ctaTypeNameUID":"enjoy-new-york","form-url":"F-22827166628","city":null,"address":null}}]
const result = fn(
childObject,
intersectionBy(parentObjectOverrideable, childObject, 'cta_type.ctaTypeNameUID')
)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG+ljU96qKRCWh+quCY7yefSmlkQw1ANQ==" crossorigin="anonymous"></script>
使用 lodash/fp 可以跳过中间值,将 _.mergeWith()
替换为 _.mergeAllWith()
,它处理数组:
const { flow, intersectionBy, concat, groupBy, flatMap, mergeAllWith, isObject, isUndefined, isNull } = _
const fn = flow(
concat,
groupBy('cta_type.ctaTypeNameUID'),
flatMap(mergeAllWith((a, b) => {
if(isObject(a) || isObject(b)) return undefined
return !isUndefined(b) && isNull(a) ? b : a
}))
)
const parentObjectOverrideable = [{"cta_type":{"title":null,"ctaTypeNameUID":"enjoy-new-york","form-url":"F-2009","city":"New York","address":null}},{"cta_type":{"title":null,"ctaTypeNameUID":"enjoy-london","form-url":"F-2010","city":"London","address":null}}]
const childObject = [{"cta_type":{"title":"Enjoy London","ctaTypeNameUID":"enjoy-london","form-url":"F-2009","city":null,"address":null}},{"cta_type":{"title":"Enjoy New York","ctaTypeNameUID":"enjoy-new-york","form-url":"F-22827166628","city":null,"address":null}}]
const result = fn(
childObject,
intersectionBy('cta_type.ctaTypeNameUID', parentObjectOverrideable, childObject)
)
console.log(result)
<script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>
我有 2 个 collection,“parent”和“child”collection。
我需要:
通过 ctaTypeNameUID
在 parent 中找到 child 项如果 child object 值是 parent object 应该被 child object 覆盖不为空。
保持child
的顺序仅保留 child 中存在的 parent 项 + 来自 child
的自定义项
Parent Object
"parentObjectOverrideable": [{
"cta_type": {
"title": null,
"ctaTypeNameUID": "enjoy-new-york",
"form-url": "F-2009",
"city": "New York",
"address": null
}
},
{
"cta_type": {
"title": null,
"ctaTypeNameUID": "enjoy-london",
"form-url": "F-2010",
"city": "London",
"address": null
}
}
]
Child Object
"childObject": [{
"cta_type": {
"title": "Enjoy London",
"ctaTypeNameUID": "enjoy-london",
"form-url": "F-2009",
"city": null,
"address": null
}
},
{
"cta_type": {
"title": "Enjoy New York",
"ctaTypeNameUID": "enjoy-new-york",
"form-url": "F-22827166628",
"city": null,
"address": null
}
},
]
我试过使用 Lodash 的 _mergeWith
const result = _.mergeWith([], parentObjectOverrideable, childObject, (a, b) =>
b === null || b === '' ? a : undefined
)
问题是,如果 cta_type 在 child object 上的位置不同,它也会覆盖 UID,所以你会得到这样的东西:
"parentObjectOverrideable": [{
"cta_type": {
"title": "Enjoy London",
,
"ctaTypeNameUID": "enjoy-new-york",
"form-url": "F-2009"
"city": null "address": null
}
},
{
"cta_type": {
"title": "Enjoy New York",
"ctaTypeNameUID": "enjoy-london",
"form-url": "F-2010",
"city": null,
"address": null
}
}
]
我也试过这样做
const overrideObject = (objA, objB) => {
const newObject = { ...objB
}
Object.keys(objA).forEach((key) => {
if (objA[key]) {
newObject[key] = objA[key]
}
})
console.log(newObject)
}
知道怎么做吗?
将项目连接到单个数组,将其分组 cta_type.ctaTypeNameUID
,然后将每个组合并到单个对象,让 _.mergeBy()
处理对象和数组的合并,并使用 [= 处理原语16=] 除非它是 null
,而 b
不是 undefined
。
const { flow, concat, groupBy, flatMap, mergeWith, isObject, isUndefined, isNull, intersectionBy } = _
const fn = flow(
concat,
arr => groupBy(arr, 'cta_type.ctaTypeNameUID'),
groups => flatMap(groups, group => mergeWith({}, ...group, (a, b, k) => {
if(isObject(a) || isObject(b)) return undefined
return !isUndefined(b) && isNull(a) ? b : a
})),
)
const parentObjectOverrideable = [{"cta_type":{"title":null,"ctaTypeNameUID":"enjoy-new-york","form-url":"F-2009","city":"New York","address":null}},{"cta_type":{"title":null,"ctaTypeNameUID":"enjoy-london","form-url":"F-2010","city":"London","address":null}}]
const childObject = [{"cta_type":{"title":"Enjoy London","ctaTypeNameUID":"enjoy-london","form-url":"F-2009","city":null,"address":null}},{"cta_type":{"title":"Enjoy New York","ctaTypeNameUID":"enjoy-new-york","form-url":"F-22827166628","city":null,"address":null}}]
const result = fn(
childObject,
intersectionBy(parentObjectOverrideable, childObject, 'cta_type.ctaTypeNameUID')
)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG+ljU96qKRCWh+quCY7yefSmlkQw1ANQ==" crossorigin="anonymous"></script>
使用 lodash/fp 可以跳过中间值,将 _.mergeWith()
替换为 _.mergeAllWith()
,它处理数组:
const { flow, intersectionBy, concat, groupBy, flatMap, mergeAllWith, isObject, isUndefined, isNull } = _
const fn = flow(
concat,
groupBy('cta_type.ctaTypeNameUID'),
flatMap(mergeAllWith((a, b) => {
if(isObject(a) || isObject(b)) return undefined
return !isUndefined(b) && isNull(a) ? b : a
}))
)
const parentObjectOverrideable = [{"cta_type":{"title":null,"ctaTypeNameUID":"enjoy-new-york","form-url":"F-2009","city":"New York","address":null}},{"cta_type":{"title":null,"ctaTypeNameUID":"enjoy-london","form-url":"F-2010","city":"London","address":null}}]
const childObject = [{"cta_type":{"title":"Enjoy London","ctaTypeNameUID":"enjoy-london","form-url":"F-2009","city":null,"address":null}},{"cta_type":{"title":"Enjoy New York","ctaTypeNameUID":"enjoy-new-york","form-url":"F-22827166628","city":null,"address":null}}]
const result = fn(
childObject,
intersectionBy('cta_type.ctaTypeNameUID', parentObjectOverrideable, childObject)
)
console.log(result)
<script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>