Javascript 在数组中的特定位置替换元素而不使其突变
如何在不改变阵列的情况下执行以下操作:Javascript 在数组中的特定位置替换元素而不使其突变,javascript,arrays,ecmascript-6,immutability,Javascript,Arrays,Ecmascript 6,Immutability,如何在不改变阵列的情况下执行以下操作: let array = ['item1']; console.log(array); // ['item1'] array[2] = 'item2'; // array is mutated console.log(array); // ['item1', undefined, 'item2'] 在上面的代码中,数组变量发生了变异。如何在不改变数组的情况下执行相同的操作?您只需设置一个新数组即可: const newItemArray = array.s
let array = ['item1'];
console.log(array); // ['item1']
array[2] = 'item2'; // array is mutated
console.log(array); // ['item1', undefined, 'item2']
在上面的代码中,
数组
变量发生了变异。如何在不改变数组的情况下执行相同的操作?您只需设置一个新数组即可:
const newItemArray = array.slice();
然后为您希望有值的索引设置值
newItemArray[position] = newItem
把那个还给我。中间索引下的值将具有未定义的
或者明显的替代方案是:
Object.assign([], array, {<position_here>: newItem});
Object.assign([],数组,{:newItem});
var列表1=['a','b','c'];
var list2=list1.slice();
列表2.拼接(2,0,“β”,“γ”);
console.log(列表1);
console.log(列表2)代码>从技术上讲,这不会被替换,因为您正在更改的索引中没有任何项
看看Clojure是如何处理它的——Clojure是一种围绕不可变数据结构的规范实现构建的语言
(assoc [1] 2 3)
;; IndexOutOfBoundsException
它不仅失败了,而且也崩溃了。这些数据结构被设计为尽可能健壮,当您遇到此类错误时,通常不是因为您发现了边缘情况,而是更可能是因为您使用了错误的数据结构
如果使用稀疏数组结束,则考虑用对象或映射来建模它们。
let items = { 0: 1 };
{ ...items, 2: 3 };
// => { 0: 1, 2: 3 }
let items = new Map([ [0, 1] ]);
items(2, 3);
// => Map {0 => 1, 2 => 3}
然而,Map是一个基本上可变的数据结构,所以您需要将其替换为一个具有类似or的库的不可变变量
当然,想要使用JavaScript的数组可能有一个很好的理由,所以这里有一个很好的解决方案
function set(arr, index, val) {
if(index < arr.length) {
return [
...arr.slice(0, position),
val,
...arr.slice(position + 1)
];
} else {
return [
...arr,
...Array(index - arr.length),
val
];
}
}
功能集(arr、索引、val){
if(索引
您可以使用对象。分配
:
Object.assign([], array, {2: newItem});
我想这样做:
function update(array, newItem, atIndex) {
return array.map((item, index) => index === atIndex ? newItem : item);
}
通常,数组排列操作会为您生成很少的临时数组,但map
不会,因此它可以更快。您还可以将快速方式作为参考
见(感谢)
相关职位:
另一种方法是使用带有切片的spread运算符作为
设newVal=33,位置=3;
设arr=[1,2,3,4,5];
设newArr=[…arr.slice(0,位置-1),newVal,…arr.slice(位置)];
控制台日志(newArr)//日志[1,2,33,4,5]
控制台日志(arr)//日志[1,2,3,4,5]
这个怎么样:
const newArray=[…array];//制作原始数组的副本
newArray[2]=“item2”;//对副本进行变异
我发现意图比这一行更清楚:
constnewarray=Object.assign([…数组],{2:'item2'});
@DanPrince不确定这些共享结构是如何实现的。但是slice复制整个数组,因此情况也是O(n)。也就是说,使用slice
复制数组可能更快,因为length
是先复制的,所以可以进行预分配<代码>对象.assign(array.slice(),{2:newItem})代码>是另一种可能性。不确定这是否是原始海报正在编写的程序中的一次性修复,或者最终结果是跨多个设备和浏览器访问应用程序,但。。。不支持internet explorer
或android
。您可能需要在答案中添加免责声明并引用polyfill。@cemper93它可以工作,您只需要使用以下特定语法:Object.assign([],array,{[i]:newItem})
不确定,但当分配给大于数组长度的索引时,这可能对引擎性能优化非常不利?很好,但redux讨论的是删除元素,我认为替换元素的最快方法是;)如果你想要快一点的东西,;)对+1.这里是一个性能比较-
function update(array, newItem, atIndex) {
return array.map((item, index) => index === atIndex ? newItem : item);
}
function replaceAt(array, index, value) {
const ret = array.slice(0);
ret[index] = value;
return ret;
}