Immutable - 使用切片(而非splice)更改数组中的元素

19

如何才能更改3/4个元素?期望输出为[1,2,4,3,5]

let list = [1,2,3,4,5];
const removeElement = list.indexOf(3); // remove number 3
list.slice(0, removeElement).concat(list.slice(removeElement+1)) // [1,2,4,5]

...在不使用splice的情况下,在数字4后面插入数字3


但是为什么不用splice呢?Splice就是为了这个目的而设计的... - Dellirium
3
@Dellirium Array.prototype.splice()不是不可变的,它会修改给定的数组。看起来OP正在寻找一个不可变的解决方案。 - chrisg86
1
@chrisg86 我敢肯定当我写下那个评论时,问题的措辞不是那样的,但我可能记错了。slice().splice()可以用于不可变性。 - Dellirium
2
slice().splice()(复制并使用splice)不起作用,因为splice返回已删除的元素,而不是更新后的数组。 - mb7744
将最后一行创建的新数组直接抛到某个变量中。 - David Peer
6个回答

29

slice不会改变其操作的数组,因此您需要将其返回值赋值给一个新变量来修改原数组。

let list = [1,2,3,4,5];
const removeElement = list.indexOf(3); // remove number 3
var newList = list.slice(0, removeElement).concat(list.slice(removeElement+1)) // [1,2,4,5]

如果您准备使用ES2015语法,您可以使用扩展运算符,如下所示:

const removeElement = list.indexOf(3); // remove number 3
var es6List = [
  ...list.slice(0, removeElement),
  ...list.slice(removeElement+1)
];
console.log(es6List);

fiddle


请注意,这并不严格回答问题,因为它缺少将3推到4之后的最后一部分。 - icc97

11

最简单的方法是使用扩展运算符:

let newList = [...list.slice(0, 2), list[3], list[2], ...list.slice(4)];

编辑队列已满,但这里存在一个偏移错误(应该是list[3],list[2]以生成[1,2,4,3,5])。 - JimmyM

4
更简单的解决方案可能是使用filter而不是splice或slice。 根据文档https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter,它会创建一个新数组,其中包含通过提供函数实现的测试的所有元素。这意味着原始数组保持不变。 唯一的区别在于,此时您必须知道要删除的值而不是索引。请注意:保留HTML标记。
let list = [1,2,3,4,5];
list.filter((item) => item !== 3);

1
这样可以去掉3,但是你需要在4之后将其注入回数组中。这就是你需要使用splice的地方。 - icc97

3

实际上,Object.assign 在这里是起作用的。

const newList = Object.assign([], list, {
  2: list[3],
  3: list[2],
});

list // [1,2,3,4,5]
newList // [1,2,4,3,5]
newList === list // false

3
var list = [1,2,3,4,5];
var numToRemove = 3;

var removeElementIndex = list.indexOf(numToRemove);
var afterRemoveElement = list[removeElementIndex+1];

list.slice(0, removeElementIndex).concat(afterRemoveElement).concat(numToRemove).concat(list.slice(removeElementIndex+2)) // [1,2,4,3,5]

-2

数组是对象,使用Object.assign()并通过属性名称表达式访问元素。

var numToMove = 2;
console.log(Object.assign(list, {[numToMove]: list[numToMove+1]}, 
{[numToMove+1]: list[numToMove]}));
// [1, 2, 4, 3, 5]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接