如何实现一个函数 lodash.merge
Issue 欢迎在 Gtihub Issue 中回答此问题: Issue 498
Author 回答者: shfshanyue
Array.prototype.flatMap
已经是 EcmaScript 的标准,看一个例子,它的输出是多少?
[1, 2, [3], 4].flatMap((x) => x + 1);
//=> [2, 3, '31', 5]
很可惜,不是 [2, 3, 4, 5]
,原因在于 flatMap
实际上是先 map
再 flat
,实现如下
Array.prototype.flatMap = function (mapper) {
return this.map(mapper).flat();
};
Author 回答者: hwb2017
const getRawType = (val) => {
return Object.prototype.toString.call(val).slice(8, -1);
};
const isPlainObject = (val) => {
return getRawType(val) === "Object";
};
const isPlainObjectOrArray = (val) => {
return isPlainObject(val) || Array.isArray(val);
};
const merge = (object, ...sources) => {
for (const source of sources) {
for (const key in source) {
if (source[key] === undefined && key in object) {
continue;
}
if (isPlainObjectOrArray(source[key])) {
if (
isPlainObjectOrArray(object[key]) &&
getRawType(object[key]) === getRawType(source[key])
) {
if (isPlainObject(object[key])) {
merge(object[key], source[key]);
} else {
object[key] = object[key].concat(source[key]);
}
} else {
object[key] = source[key];
}
} else {
object[key] = source[key];
}
}
}
};
// merge array
var object = {
a: [{ b: 2 }, { d: 4 }],
};
merge(object, { a: [{ c: 3 }, { e: 5 }] });
console.log(object);
// merge object
var object = {
a: { b: { c: 1 } },
};
merge(object, { a: { b: { d: 2 } } });
console.log(object);
// overwrite primitive value
object = {
a: { b: 1 },
};
merge(object, { a: { b: 2 } });
console.log(object);
// skip undefined
object = {
a: { b: 1 },
};
merge(object, { a: { b: undefined } });
console.log(object);
// multiple sources
var object = {
a: { b: { c: 1, d: [1] } },
};
merge(object, { a: { b: { e: 2 } } }, { a: { b: { d: [2] } } });
console.log(JSON.stringify(object));