Javascript ES6,是从数组中删除项目或从数组中删除项目的最佳方法

时间:2020-01-10 13:04:27

标签: javascript arrays node.js ecmascript-6

我在这里编写一些代码,以使用以下逻辑在数组上添加元素

如果元素存在于数组中,则该函数应从数组中删除该元素并返回不包含给定元素的数组,否则应返回其后附加给定元素的数组。

记住这一点,我在想是否有更好的方法可以做到这一点,这就是我为此编写的代码。

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)算法

4 个答案:

答案 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()]);

相关问题