我在这里编写一些代码,以使用以下逻辑在数组上添加元素
如果元素存在于数组中,则该函数应从数组中删除该元素并返回不包含给定元素的数组,否则应返回其后附加给定元素的数组。
记住这一点,我在想是否有更好的方法可以做到这一点,这就是我为此编写的代码。
function filterArray(arr, obj, key) {
for (let i = 0; i < arr.length; i++) {
if (arr[i][key] === obj[key]) {
const newArr = [...arr]
newArr.splice(i, 1)
return newArr
}
}
return [...arr, obj]
}
const fruits = [
{ id: 1, fruit: "Apple" },
{ id: 2, fruit: "Banana" },
{ id: 3, fruit: "Pineapple" }
]
const removedBanana = filterArray(fruits, {
id: 3,
fruit: "Banana"
}, "fruit")
const addedStrawberry = filterArray(fruits, {
id: 4,
fruit: "Strawberry"
}, "fruit")
console.log(removedBanana) // [ { id: 1, fruit: 'Apple' }, { id: 3, fruit: 'Pineapple' } ]
console.log(addedStrawberry)
// [
// { id: 1, fruit: 'Apple' },
// { id: 2, fruit: 'Banana' },
// { id: 3, fruit: 'Pineapple' },
// { id: 4, fruit: 'Strawberry' }
// ]
在ES6上有更好的方法吗?
编辑
如果可能的话,我只想迭代一次数组,进行O(n)算法
答案 0 :(得分:5)
此方法通过查找索引和拼接(如果找到)或将对象推入数组来使数组变异。结果具有与移交数组相同的对象引用。
function filterArray(array, object, key) {
var index = array.findIndex(o => o[key] === object[key]);
if (index === -1) array.push(object);
else array.splice(index, 1);
return array;
}
const
fruits = [{ id: 1, fruit: "Apple" }, { id: 2, fruit: "Banana" }, { id: 3, fruit: "Pineapple" }];
console.log(filterArray(fruits, { id: 3, fruit: "Banana" }, "fruit"));
console.log(filterArray(fruits, { id: 4, fruit: "Strawberry" }, "fruit"));
.as-console-wrapper { max-height: 100% !important; top: 0; }
对于非变异方法,您可以在函数的开头获取一个副本,并执行与上面相同的操作。
function filterArray([...array], object, key) {
function filterArray(array, object, key) {
var index = array.findIndex(o => o[key] === object[key]);
if (index === -1) array.push(object);
else array.splice(index, 1);
return array;
}
const
fruits = [{ id: 1, fruit: "Apple" }, { id: 2, fruit: "Banana" }, { id: 3, fruit: "Pineapple" }];
console.log(filterArray(fruits, { id: 3, fruit: "Banana" }, "fruit"));
console.log(filterArray(fruits, { id: 4, fruit: "Strawberry" }, "fruit"));
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 1 :(得分:2)
您可以使用Array.some()
检查对象是否存在,以及是否将其过滤掉。如果没有,请添加它。
function filterArray(arr, obj, key) {
return arr.some(o => obj[key] === o[key]) ? // if you can find the object
arr.filter(o => obj[key] !== o[key]) // remove it
:
[...arr, obj] // or add it if not
}
const fruits = [{"id":1,"fruit":"Apple"},{"id":2,"fruit":"Banana"},{"id":3,"fruit":"Pineapple"}]
const removedBanana = filterArray(fruits, { id: 3, fruit: "Banana" }, "fruit")
const addedStrawberry = filterArray(fruits, { id: 4, fruit: "Strawberry" }, "fruit")
console.log(removedBanana) // [ { id: 1, fruit: 'Apple' }, { id: 3, fruit: 'Pineapple' } ]
console.log(addedStrawberry)
// [
// { id: 1, fruit: 'Apple' },
// { id: 2, fruit: 'Banana' },
// { id: 3, fruit: 'Pineapple' },
// { id: 4, fruit: 'Strawberry' }
// ]
答案 2 :(得分:1)
此问题有一个简单的解决方案:
function addObjToArray (arr, obj, key) {
const resultArr = arr.filter(arrObj => arrObj[key] !== obj[key])
if (resultArr.length === arr.length) resultArr.push(obj)
return resultArr
}
filter
方法将返回仅包含与obj[key]
不同的对象的数组。如果过滤后的数组等于原始数组,则将对象推送到resultArr
,否则,将返回初始的resultArr
。
这是我的同事(https://stackoverflow.com/users/12691758/guilherme-ca%c3%a7ador-monteiro)的解决方案。
您的想法?
答案 3 :(得分:0)
根据您的要求以及注释中对集合进行变异的其他要求,通过使用ES6 Map
,您将拥有更好的工具:
const fruits = new Map([
{ id: 1, fruit: "Apple" },
{ id: 2, fruit: "Banana" },
{ id: 3, fruit: "Pineapple" }
].map (o => [o.fruit, o]));
fruits.key = "fruit"; // register the key field once
fruits.toggleItem = function (obj) {
if (!this.delete(obj[this.key])) this.set(obj[this.key], obj);
}
fruits.toggleItem({id: 3, fruit: "Banana"});
console.log([...fruits.values()]);
fruits.toggleItem({id: 4, fruit: "Strawberry"});
console.log([...fruits.values()]);