Javascript ES6,如果存在则从数组中删除项目的最佳方法,如果不存在则添加
Posted
技术标签:
【中文标题】Javascript ES6,如果存在则从数组中删除项目的最佳方法,如果不存在则添加【英文标题】:Javascript ES6, best way to remove item from array if it exists or add if doesn't exists 【发布时间】:2020-04-28 03:20:41 【问题描述】:我在这里写了一些代码,用以下逻辑在数组上添加一个元素
如果该元素存在于数组中,该函数应该从数组中移除该元素并返回没有给定元素的数组,否则它应该返回附加给定元素的数组。
考虑到这一点,我正在考虑是否有更好的方法来做到这一点,这就是我为此编写的代码。
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) 算法
【问题讨论】:
你想改变数组吗? @NinaScholz 是的 您的代码显示了一个新数组 ... 操作,对不起@NinaScholz,我不想变异,我想创建一个新的 【参考方案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://***.com/users/12691758/guilherme-ca%c3%a7ador-monteiro) 提供的解决方案。
你怎么看?
【讨论】:
来自***.com/users/12691758/…【参考方案2】:这种方法通过查找索引和拼接(如果找到)或将对象推送到数组来改变数组。结果与移交的数组具有相同的对象引用。
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;
【讨论】:
将不得不移动到杜塞尔多夫前 12 小时的某个时区才能有机会获得一些代表。会用三元运算符做到这一点,但splice()
/push()
夫妇似乎在这种特殊情况(尤其是与findIndex()
一起)。赞成。
@YevgenGorbunkov,三元组不起作用,因为参数不同。
三元运算符 works 非常适合“变异”方法
...以及在函数参数中使用扩展语法进行非变异【参考方案3】:
根据您的要求,以及附加要求(在 cmets 中)集合应该变异,使用 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()]);
【讨论】:
【参考方案4】:您可以使用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'
// ]
【讨论】:
filter()
循环遍历整个数组,some()
循环直到匹配在最坏的情况下 2 次通过。仍然是 O(n),但似乎不是性能最好的解决方案。我猜,there's 更短。
注意解决方案之间的区别 - 我的不会改变数组。为了使事物在没有过滤器的情况下保持不变,您仍然需要首先找到项目的索引 - O(n),如果存在,也复制数组 (O(n))。所以不可变需要 O(2n) -> O(n)。以上是关于Javascript ES6,如果存在则从数组中删除项目的最佳方法,如果不存在则添加的主要内容,如果未能解决你的问题,请参考以下文章