这里有两个对象:
const obj1 = {a: null, b: "b"}
const obj2 = {a: "a", b: null}
如何合并这两个对象并得到以下对象?
{a: "a", b: "b"}
我可以做到这一点:
const merged = {...obj1, ...obj2}
但它返回了这个结果:
{ a: "a", b: null }
有没有一种方法可以合并两个对象,同时更倾向于非空(非空、未定义等)值?
这里有两个对象:
const obj1 = {a: null, b: "b"}
const obj2 = {a: "a", b: null}
{a: "a", b: "b"}
const merged = {...obj1, ...obj2}
{ a: "a", b: null }
function merge(obj1, obj2) {
answer = {}
for(key in obj1) {
if(answer[key] === undefined || answer[key] === null)
answer[key] = obj1[key];
}
for(key in obj2) {
if(answer[key] === undefined || answer[key] === null)
answer[key] = obj2[key];
}
return answer
}
!answer[key]
对于像 "false" 或 "0" 这样的值将会是 true。我认为更好的方法是仅显式检查 null 值。 - Lixconst
、let
或 var
声明变量。 - mwieczorek我建议使用 Lodash 的 mergeWith 函数来实现:
const obj1 = {a: null, b: "b"}
const obj2 = {a: "a", b: null}
const result = _.mergeWith({}, obj1, obj2,
(a, b) => b === null ? a : undefined
)
// result: {a: "a", b: "b"}
对于对象key
,使用简单的forEach()
循环怎么样?它可以同时处理null
和undefined
值:
const obj1 = {a: null, b: "b"};
const obj2 = {a: "a", b: null};
const merged = {};
Object.keys(obj1).forEach((key) => merged[key] = obj1[key] ? obj1[key] : obj2[key]);
console.log(merged);
const obj1 = {a: null, b: "b"}
const obj2 = {a: "a", b: null}
const obj3 = {}
for (var k in obj1) {
obj3[k] = obj1[k] ? obj1[k] : obj2[k];
}
console.log(obj3);
yarn add @ramda/mergedeepwith flat ramda
import { default as flat } from "flat";
import mergeDeepWith from "@ramda/mergedeepwith";
import * as R from "ramda";
const obj1 = {
a: null,
b: "bbb",
c: {
"c-1": "cccc",
},
d: [
{
"d-1": "ddd-1",
},
{
"d-2": null,
},
{
"d-3": [0, 1, "a", 100], // omit 0
},
],
};
const obj2 = {
a: "aaa",
b: null,
c: {
"c-1": null,
},
d: [
{
"d-1": null,
},
{
"d-2": "ddd-2",
},
{
"d-3": ["b", "c"],
},
],
};
const flattenedObj1 = flat.flatten(obj1);
const flattenedObj2 = flat.flatten(obj2);
const mergedObj = R.mergeDeepWith(
(x, y) => {
if (x) return x;
if (y) return y;
return null;
},
flattenedObj2,
flattenedObj1
);
console.log(JSON.stringify(flat.unflatten(mergedObj), null, 2));
$ node index.js
{
"a": "aaa",
"b": "bbb",
"c": {
"c-1": "cccc"
},
"d": [
{
"d-1": "ddd-1"
},
{
"d-2": "ddd-2"
},
{
"d-3": [
"b",
"c",
"a",
100
]
}
]
}
function merge(obj1, obj2) {
let merged = { ...obj1 }
for (key in obj2) {
if (merged[key] === undefined || merged[key] === null)
merged[key] = obj2[key];
}
return merged
}
为了完整起见,有人应该提到 空值合并运算符
因此,对于顶层属性,您可以选择非空值的属性:
const obj1 = { a: null, b: "b" }
const obj2 = { a: "a", b: null }
const obj3 = { foo: Infinity }
let merge = (...objects) =>
objects
.reduce((result, next) => ({ ...result, ...Object.entries(next)
.reduce((resultingEntries, [key, value]) => ({ ...resultingEntries, [key]: value ?? result[key] }), {})}))
merge(obj1, obj2, obj3)
// {a: "a", b: "b", foo: "c"}
如果您还想复制更深层次的属性,事情就会变得非常棘手:
let merge2 = (...objects) =>
objects
.reduce((result, next) => ({ ...result, ...Object.entries(next)
.reduce((resultingEntries, [key, value]) => ({ ...resultingEntries, [key]:
result && result[key] && typeof result[key] === 'object' // <- null unsafe here
? merge3(...objects.map(o => o && o[key]))
: value ?? result[key] // <- to here?
}), {})}))
或许最好将其提取到一个函数中
const getProps = (key, ...objects) => objects.filter(isntNullOrUndefined).map(o => o[key]).filter(isntNullOrUndefined)
const isntNullOrUndefined = x => x !== null && x !== undefined
const merge2 = (...objects) =>
objects
.filter(isntNullOrUndefined)
.reduce((acc, obj) => ({
...acc,
...Object
.keys(obj)
.filter(key => !(key in acc))
.filter(key => isntNullOrUndefined(obj[key]))
.reduce((acc2, key) => ({
...acc2,
[key]: typeof obj[key] === 'object'
? merge2(...getProps(key, ...objects))
: getProps(key, ...objects)[0]
}), {})
}), {})
你可以创建一个函数,将对象数组作为参数传递。
这样,无论你有多少个对象,你都将得到它们合并在一起的结果,不包括 undefined 和 null 值。只需将它们作为数组发送即可。
在函数中,你需要传入所有的对象,进行映射,并使用for (const [key, value] of Object.entries(obj))
遍历它们的键和值,然后排除那些值为 undefined
或 null
的对象。
请看下方示例:
const obj1 = {
a: null,
b: "goodb",
c: 0,
}
const obj2 = {
a: "gooda",
b: null,
c: undefined
}
function cleanObjects(arr) {
let o = {}
arr.map((obj) => {
for (const [key, value] of Object.entries(obj)) {
typeof value === 'undefined' || value === null ?
delete obj[key] : o[key] = value;
}
})
return o;
}
const result = cleanObjects([obj1, obj2])
console.log(result)
const obj1 = {
a: null,
b: "goodb",
c: 0,
d: 133,
f: null
}
const obj2 = {
a: "gooda",
b: null,
e: 1,
c: undefined
}
function cleanObjects(arr) {
let o = {}
arr.map((obj) => {
for (const [key, value] of Object.entries(obj)) {
typeof value === 'undefined' || value === null ?
delete obj[key] : o[key] = value;
}
})
return o;
}
const result = cleanObjects([obj1, obj2])
console.log(result)
merge
的函数,它会覆盖下一个非空值并将所有对象的属性添加到一个单一对象中。/* @/utils.js */
Object.merge = function (...objs) {
const obj = {};
objs.reduce((prevObj, currentObj) => {
if (typeof prevObj === 'object' && typeof currentObj === 'object') Object.entries(currentObj).forEach(([k, v]) => {
obj[k] = v === null || v === undefined
? prevObj[k]
: v;
});
return obj;
}, {});
return obj;
};
/* @/app.js */
Object.merge(a,b,c,...z);
Object.merge = function (...objs) {
const obj = {};
objs.reduce((prevObj, currentObj) => {
if (typeof prevObj === 'object' && typeof currentObj === 'object') Object.entries(currentObj).forEach(([k, v]) => {
obj[k] = v === null || v === undefined
? prevObj[k]
: v;
});
return obj;
}, {});
return obj;
}
const john = {
name: 'John Doe',
age: 40,
heigth: '5.3ft'
}
const jane = {
name: 'Jane Doe',
age: null,
heigth: '4.1ft'
}
const mark = {
name: 'Mark',
age: 35,
heigth: null
}
const ghost = {
name: null,
age: null,
heigth: null,
planet: 'unknown'
}
const noname = {
name: null,
age: 100,
heigth: '100ft',
planet: '100M-E'
}
console.log(Object.merge(john,jane,mark,ghost,noname))
null
检查? - Jonas Wilms(:
- Ele