不可变 - 使用切片更改数组中的元素(无拼接)

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 就是为此目的而设计的…… @Dellirium Array.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]

【讨论】:

以上是关于不可变 - 使用切片更改数组中的元素(无拼接)的主要内容,如果未能解决你的问题,请参考以下文章

元组&字典

数据类型

python数据类型的区别

集合的特点

GoLang笔记-数组和切片,本质是就是长度不可变的可变的区别

使用numpy数组更改python pandas数据框切片中的元素[重复]