2016-06-14 23 views
2

我一直在观看来自Dan Abramov的012x的视频avoiding-array-mutations,并且我已经计算出如何使用slice通过id从数组中删除元素,返回新的数组没有突变。使用切片或传播从JavaScript中的数组中删除元素

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,然后返回新的数组,因此基本上可以拼接,但没有突变。

+0

'[... arr]'与'arr相同。切片()',你可以“切片和拼接”没有任何副作用删除 –

+0

在视频中,他告诉你这样做的方式与数组传播''[arrayOld.slice(0,索引),.. .arrayOld.slice(index + 1)]''' – ferndopolis

回答

8

为什么不过滤它?

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

这将返回一个新的数组,只有满足谓词函数的元素。


注:这不能被用作是在特定索引以除去只是一个元件,或仅一个元件。如果是这样的话,你可以简单地做这样的

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

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

+0

保存已过滤的索引可能会比使用索引过滤更清晰'let indices = []; arr.filter((e,i)=> {if(e === foo){indices.push(i); return false;} return true;});' –

1

嗯,我已经对这个问题进行了一些思考,因为在功能性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 
2

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

但是,如果你想使用传播运营商,以消除索引的元素,你可以做到以下几点:

```

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

```