覆盖已经存在的数组对象,否则添加到数组中



当我运行这个例子时,我希望elementThatAllreadyExist用名称test1覆盖现有对象,它正确地做到了。

当我用arr2运行示例时,我希望newElement元素被添加到数组中,因为数组中不存在具有name"test33"的对象,但没有元素被添加到数组中。

为什么它忽略了我的|| obj回退?

let arr = [{
name: "test1",
values: {
value1: 1,
value2: 2,
value3: 3,
}
},
{
name: "test2",
values: {
value1: 1,
value2: 2,
value3: 3,
}
},
{
name: "test3",
values: {
value1: 1
}
},
{
name: "test4",
values: {
value1: 1,
value2: 2,
value3: 3,
}
}
]
let elementThatAllreadyExists = [{
name: "test1",
values: {
value1: 3323,
value2: 2323,
value3: 2323,
}
}]
let newElement = [{
name: "test33",
values: {
value1: 666,
value2: 666,
value3: 663,
}
}]
const arr1 = arr.map(obj => newElement.find(o => o.name === obj.name) || obj);
console.log(arr1)
const arr2 = arr.map(obj => elementThatAllreadyExists.find(o => o.name === obj.name) || obj);
console.log(arr2)

将我的评论转换为答案,当.find()arr中的每个元素返回null时,就像newElement一样,然后|| obj回退分支为每个元素运行,map返回浅拷贝。所以它根本没有忽略|| obj。事实上,这就是它所做的(当元素不存在时)。

map不添加元素,它转换现有的元素。你可以使用push

作为题外话,newElementelementThatAllreadyExists作为一个元素的数组是奇怪的。如果这些变量名应该是数组,那么它们应该是复数形式的。如果它们是单数,则删除数组以使它们成为普通对象。在所有你不打算重新赋值的变量声明上使用const(这应该是几乎所有的)。

这是函数。如果您的输入确实是数组,则循环遍历它们并调用addOrReplaceExisting函数,但要注意时间复杂度是二次的。您可能希望使用Map或由name键控的对象。.set()方法已经实现了"replace或"行为,在键上实现唯一性。对于查找和替换,映射是0(1)。

const replaceOrAdd = (arr, el, key="name") => {
const existingIndex = arr.findIndex(e => e[key] === el[key]);
if (existingIndex >= 0) {
arr[existingIndex] = el;
}
else {
arr.push(el);
}
};
const arr = [{ name: "test1", values: { value1: 1, value2: 2, value3: 3, } }, { name: "test2", values: { value1: 1, value2: 2, value3: 3, } }, { name: "test3", values: { value1: 1 } }, { name: "test4", values: { value1: 1, value2: 2, value3: 3, } } ];
const elementThatAlreadyExists = { name: "test1", values: { value1: 3323, value2: 2323, value3: 2323, } };
const newElement = { name: "test33", values: { value1: 666, value2: 666, value3: 663, } };
replaceOrAdd(arr, elementThatAlreadyExists);
replaceOrAdd(arr, newElement);
console.log(arr);

Immuable版本:

const replaceOrAdd = (arr, el, key="name") => {
const existingIndex = arr.findIndex(e => e[key] === el[key]);
if (existingIndex >= 0) {
return Object.freeze([
...arr.slice(0, existingIndex),
el,
...arr.slice(existingIndex + 1),
]);
}
return Object.freeze(arr.concat(el));
};
const arr = Object.freeze([{ name: "test1", values: { value1: 1, value2: 2, value3: 3, } }, { name: "test2", values: { value1: 1, value2: 2, value3: 3, } }, { name: "test3", values: { value1: 1 } }, { name: "test4", values: { value1: 1, value2: 2, value3: 3, } } ]);
const elementThatAlreadyExists = { name: "test1", values: { value1: 3323, value2: 2323, value3: 2323, } };
const newElement = { name: "test33", values: { value1: 666, value2: 666, value3: 663, } };
const arr1 = replaceOrAdd(arr, elementThatAlreadyExists);
const arr2 = replaceOrAdd(arr1, newElement);
console.log(arr2);

Mapversion:

const arr = [{ name: "test1", values: { value1: 1, value2: 2, value3: 3, } }, { name: "test2", values: { value1: 1, value2: 2, value3: 3, } }, { name: "test3", values: { value1: 1 } }, { name: "test4", values: { value1: 1, value2: 2, value3: 3, } } ];
const elementThatAlreadyExists = { name: "test1", values: { value1: 3323, value2: 2323, value3: 2323, } };
const newElement = { name: "test33", values: { value1: 666, value2: 666, value3: 663, } };
const elemsByName = new Map(arr.map(e => [e.name, e]));
elemsByName.set(
elementThatAlreadyExists.name,
elementThatAlreadyExists
);
elemsByName.set(newElement.name, newElement);
console.log([...elemsByName.values()]); // or use .get to get a single element by name

相关内容

  • 没有找到相关文章

最新更新