我有这样的情况:我正在努力反对新的key-value
对,例如:
let a1 = {key1: 'val1'};
let a2 = {key2: 'val2'};
const result = {...a1, ...a2};
结果是我得到一个有效的新对象:{key1: 'val1', key2: 'val2'}
。
但是有第三种情况:
let a1 = {key1: 'val1'};
let a2 = {key2: 'val2'};
let b1 = {key1: 'val1b'};
const result = {...a1, ...a2, ...b1};
因此我应该得到:
{key1: ['val1', 'var1b'], key2: 'val2'}`.
所以->如果已经有这样的键->将此键值转换为数组并将其推入。
我尝试过:
用于...我要推送的所有对象:
const keysToPush = Object.keys(b1);
const keysInitial = Object.keys(a1); // foreach too
if (keysInitial.includes(keysToPush)) // push as array
但是看起来很丑
也许应该有更优雅的解决方案?
答案 0 :(得分:1)
您需要查看每个属性,并确定是分配还是转换为数组并推入值。
const
migrate = (target, source) => {
Object.keys(source).forEach(key => {
if ([].concat(target[key] || []).includes(source[key])) return;
if (key in target) {
if (!Array.isArray(target[key])) target[key] = [target[key]];
target[key].push(source[key]);
} else {
target[key] = source[key];
}
});
return target;
};
var a1 = { key1: 'val1' },
a2 = { key2: 'val2' },
b1 = { key1: 'val1b' },
b2 = { key1: 'val1b' },
result = [a1, a2, b1, b2].reduce(migrate, {});
console.log(result);
答案 1 :(得分:1)
检查密钥是否存在。如果是这样,请检查它是否为数组,并相应地处理每种情况:
let a1 = {
key1: 'val1'
};
let a2 = {
key2: 'val2'
};
let b1 = {
key1: 'val1b'
};
const merge = (...o) => {
let res = o.reduce((acc, curr) => {
Object.entries(curr).forEach(([k, v]) => {
acc[k] = (acc[k] && Array.isArray(acc[k]) ? [...acc[k], v] : (acc[k] ? [acc[k], v] : v));
});
return acc;
});
return res;
};
let result = merge(a1, a2, b1);
console.log(result);
.as-console-wrapper {
max-height: 100% !important;
top: auto;
}
答案 2 :(得分:1)
我建议使用Map
(用于键)({每个键的值)Set
(用于键),因为Set
将确保没有重复的值。在过程结束时,Map
可以转换为普通对象,Set
可以转换为单个值或值数组:
// Sample input with some repetition:
const objects = [
{ key1: 'val1' },
{ key2: 'val2' },
{ key1: 'val1b' },
{ key2: 'val2' },
{ key1: 'val1b' }
];
const pairs = objects.flatMap(Object.entries);
const map = new Map(pairs.map(([k]) => [k, new Set]));
pairs.forEach(([k, v]) => map.get(k).add(v));
const result = Object.fromEntries(Array.from(map, ([k, set]) =>
set.size < 2 ? [k, ...set] : [k, [...set]]
));
console.log(result);
答案 3 :(得分:0)
您可以创建一个合并对象的函数。解决步骤为:
forEach
遍历所有对象。在forEach
内创建另一个嵌套的forEach
,以遍历对象的条目。检查键是否已存在于结果obj中。
检查其值是否为数组,然后向其推送新值。
如果不是数组,只需将其转换为两个值的数组
function mergeObjs(...objs){
const res = {};
objs.forEach(x => {
Object.entries(x).forEach(([k,v]) => {
if(res[k]){
if(Array.isArray(res[k])) res[k].push(v)
else res[k] = [res[k],v]
}
else res[k] = v;
})
})
return res;
}
let a1 = {key1: 'val1'};
let a2 = {key2: 'val2'};
let b1 = {key1: 'val1b'};
console.log(mergeObjs(a1,a2,b1))