Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在数组中的特定位置替换元素而不使其突变_Javascript_Arrays_Ecmascript 6_Immutability - Fatal编程技术网

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;
}