配列を変更せずに次の操作を実行するにはどうすればよいですか:
let array = ['item1'];
console.log(array); // ['item1']
array[2] = 'item2'; // array is mutated
console.log(array); // ['item1', undefined, 'item2']
上記のコードでは、array
変数が変更されています。配列を変更せずに同じ操作を実行するにはどうすればよいですか?
Object.assign
を使用できます:
Object.assign([], array, {2: newItem});
次のような新しい配列を設定するだけです。
const newItemArray = array.slice();
そして、値を取得したいインデックスの値を設定します。
newItemArray[position] = newItem
そしてそれを返します。中間のインデックスの下の値はundefined
になります。
または、明らかに代替案は次のとおりです。
Object.assign([], array, {<position_here>: newItem});
技術的には、これはreplaceingではありません。変更するインデックスにはアイテムがありません。
Clojure(不変データ構造の標準的な実装を中心に構築された言語)での処理方法を見てください。
(assoc [1] 2 3)
;; IndexOutOfBoundsException
失敗するだけでなく、クラッシュします。これらのデータ構造は可能な限り堅牢になるように設計されており、これらの種類のエラーに出くわすのは、通常、Edgeのケースを発見したからではなく、間違ったデータ構造を使用している可能性が高いからです。
スパース配列で終わる場合は、代わりにオブジェクトまたはマップを使用してそれらをモデリングすることを検討してください。
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は基本的に変更可能なデータ構造であるため、 Immutable.js または Mori のようなライブラリを使用して、これを不変のバリアントに交換する必要があります。
let items = Immutable.Map([ [0, 2] ]);
items.set(2, 3);
// => Immutable.Map {0 => 1, 2 => 3}
let items = mori.hashMap();
mori.assoc(items, 2, 3);
// => mori.hashMap {0 => 1, 2 => 3}
もちろん、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
];
}
}
ここに私がそれをやりたい方法があります:
function update(array, newItem, atIndex) {
return array.map((item, index) => index === atIndex ? newItem : item);
}
一般的に、Array-spread操作は一時的な配列をほとんど生成しませんが、map
は生成しないため、高速になります。また、参照として この説明 を参照することもできます。
var list1 = ['a','b','c'];
var list2 = list1.slice();
list2.splice(2, 0, "beta", "gamma");
console.log(list1);
console.log(list2);
これは、あなたの望むことですか?
別の方法は、次のようにスライスでスプレッド演算子を使用することです
let newVal = 33, position = 3;
let arr = [1,2,3,4,5];
let newArr = [...arr.slice(0,position - 1), newVal, ...arr.slice(position)];
console.log(newArr); //logs [1, 2, 33, 4, 5]
console.log(arr); //logs [1, 2, 3, 4, 5]