不可变 - 使用切片更改数组中的元素(无拼接)
Posted
技术标签:
【中文标题】不可变 - 使用切片更改数组中的元素(无拼接)【英文标题】:Immutable - change elements in array with slice (no splice) 【发布时间】:2017-04-05 20:52:46 【问题描述】:如何改变 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]
...在没有拼接的情况下在 4 号之后再推 3 号
【问题讨论】:
但是为什么没有拼接呢? Splice 就是为此目的而设计的…… @DelliriumArray.prototype.splice()
不是一成不变的。它修改给定的数组。看起来 OP 正在寻找一个不可变的解决方案。
@chrisg86 我可以发誓,当我写该评论时,这个问题并没有这样表述,但可能是错误的。 slice().splice()
工作,但不变性
slice().splice()
(复制然后使用拼接)不起作用,因为拼接返回删除的元素,而不是更新的数组
只需将最后一行创建的新数组放入某个变量中
【参考方案1】:
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 语法,你可以使用 spread 操作符,如下:
const removeElement = list.indexOf(3); // remove number 3
var es6List = [
...list.slice(0, removeElement),
...list.slice(removeElement+1)
];
console.log(es6List);
fiddle
【讨论】:
请注意,这并不能严格回答问题,因为它缺少在 4 之后推动 3 的最后部分。【参考方案2】:最简单的写法是使用展开运算符:
let newList = [...list.slice(0, 2), list[4], list[3], ...list.slice(4)];
【讨论】:
【参考方案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]
【讨论】:
【参考方案4】: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
【讨论】:
【参考方案5】:更简单的解决方案可能是使用filter
而不是拼接或切片。根据文档https://developer.mozilla.org/en-US/docs/Web/javascript/Reference/Global_Objects/Array/filter
filter() 方法创建一个新数组,其中包含通过所提供函数实现的测试的所有元素。
这意味着原始数组保持不变。唯一的区别是,在这种情况下,您必须知道要删除的值而不是索引。
let list = [1,2,3,4,5];
list.filter((item) => item !== 3);
【讨论】:
这去掉了 3,但是你需要在 4 之后将它注入到数组中。这就是你需要splice
的地方。【参考方案6】:
数组是对象,使用 Object.assign() 并通过属性名称表达式访问元素。
var numToMove = 2;
console.log(Object.assign(list, [numToMove]: list[numToMove+1],
[numToMove+1]: list[numToMove]));
// [1, 2, 4, 3, 5]
【讨论】:
以上是关于不可变 - 使用切片更改数组中的元素(无拼接)的主要内容,如果未能解决你的问题,请参考以下文章