【问题标题】:Remove an element from an array in JavaScript with slice or spread使用切片或展开从 JavaScript 中的数组中删除元素
【发布时间】:2016-10-14 19:06:49
【问题描述】:

我一直在观看 Dan Abramov avoiding-array-mutations 的关于 redux 的视频,并且我已经研究了如何使用 slice 通过 id 从数组中删除一个元素,返回没有突变的新数组。

var arrayOld = ['apple', 'orange', 'fig']
var index = arrayOld.indexOf('orange')
var arrayNew = arrayOld.slice(0,index).concat(arrayOld.slice(index + 1))
// ['apple', 'fig']

我想知道如何使用es6 spread 语法做同样的事情?

我也想知道为什么没有更简单的方法:例如es6 中的辅助函数来执行此操作,它的工作方式与 concat 方法一样简单,您可以在其中传递要删除的元素的 id 并返回新数组,因此基本上是拼接但没有突变。

【问题讨论】:

  • [...arr]arr.slice() 相同,您可以“切片和拼接”以消除副作用
  • 在视频中,他向您展示了这种使用数组传播的方式[...arrayOld.slice(0,index), ...arrayOld.slice(index+1)]

标签: javascript arrays ecmascript-6


【解决方案1】:

正如@thefourtheye 已经提到的,最好使用.filter 作为您的示例。

但是,如果您想使用扩展运算符按索引删除元素,您可以执行以下操作:


let arrayOld = ['apple', 'orange', 'fig']
let index = 1;
let arrayNew = [...arrayOld.slice(0, index), ...arrayOld.slice(index + 1)];
console.log(arrayOld);
console.log(arrayNew);

【讨论】:

    【解决方案2】:

    你为什么不过滤它?

    console.log(['apple', 'orange', 'fig'].filter(item => item !== 'orange'));
    // [ 'apple', 'fig' ]
    

    这将返回一个新数组,其中仅包含满足谓词函数的元素。


    注意:这不能用于仅删除一个元素,或仅删除特定索引处的元素。如果是这样的话,你可以简单地这样做

    var index = arrayOld.indexOf('orange')
    console.log(arrayOld.filter((item, idx) => idx !== index));
    

    传递给谓词函数的第二个参数是数组中元素的实际索引。

    【讨论】:

    • 存储过滤后的索引可能比使用索引过滤更干净let indices = []; arr.filter((e, i) => {if (e === foo) {indices.push(i); return false;}return true;});
    • 这里应该注意filter 会扫描整个数组,这对大数组来说性能不佳,如果你确实有索引就没有必要(例如,如果你在构建数组)。在这种情况下,Oleksil 提供的答案要好得多,因为它的运行时间为 O(n)。
    【解决方案3】:

    好吧,我之前已经对这个主题进行了一些思考,因为在函数式 JS 中,一些数组方法没有经过深思熟虑。所以有时他们必须稍微调整一下......有两个问题

    1. 你不应该改变不属于你的东西。
    2. 你应该返回适​​当的东西。

    因此,例如在删除项目时,根据您的用例,您可能希望将删除的项目或结果数组作为参数传递给函数,同时不改变原始数组。因此,在这种特殊情况下,您有两个选项,例如您提到的那个

    myFunction(myArr.slice(0,i).concat(a.slice(i+1))) // pass resulting array as argument
    

    或以其他方式将已删除的项目作为结果。

    myFunction(a.slice().splice(i,1)[0]) // pass deleted item as an argument
    

    【讨论】:

      猜你喜欢
      • 2020-08-14
      • 2019-02-05
      • 1970-01-01
      • 2022-12-26
      • 1970-01-01
      • 2018-08-13
      • 2016-09-16
      相关资源
      最近更新 更多