web-dev-qa-db-ja.com

コードの1行で配列エントリをスプレッド構文に置き換えますか?

...スプレッド構文を使用して、反応状態配列の項目を置き換えます。これは機能します:

let newImages = [...this.state.images]
newImages[4] = updatedImage
this.setState({images:newImages})

これを1行のコードで実行できますか?このようなもの? (これは明らかに機能しません...)

this.setState({images: [...this.state.images, [4]:updatedImage})
15
Kokodoko

Array.slice を使用します

this.setState({images: [...this.state.images.slice(0, 3), updatedImage, ...this.state.images.slice(4)]})
19
Bardia Rastin

それを提供するsyntaxはありません。 Object.assign がその仕事をします:

this.setState({images: Object.assign([...this.state.images], {4: updatedImage}));

...ただし、一時オブジェクト(最後のオブジェクト)が含まれます。それでも、一時オブジェクトは1つだけです...

通常のJS配列は実際には配列ではないため機能します1 (これはもちろん最適化の対象です)、それらはいくつかの特別な機能を持つオブジェクトです。それらの「インデックス」は実際にはプロパティ名です 特定の基準を満たしています2。そこで、this.state.imagesを新しい配列に展開し、それをObject.assignにターゲットとして渡し、Object.assign"4"という名前のプロパティを持つオブジェクトを与えます(yes 、最終的に文字列になりますが、更新する値を数値として書き込むことができます)。

実例:

const a = [0, 1, 2, 3, 4, 5, 6, 7];
const b = Object.assign([...a], {4: "four"});
console.log(b);

4を変数にできる場合は問題ありませんが、 計算されたプロパティ名 を使用できます(ES2015の新機能):

let n = 4;
this.setState({images: Object.assign([...this.state.images], {[n]: updatedImage}));

nの周りの[]に注意してください。


1 開示:それは私の貧血の小さなブログへの投稿です。

2 箇条書きリストの後の2番目の段落です。

integer indexは、正規の数値文字列(7.1.16を参照)で、数値が+の文字列値プロパティキーです。 0または正の整数≤253-1。 配列インデックスは、数値iが+0≤iの範囲にある整数インデックスです<232-1。

したがって、Object.assignは、create-the-array-then-update-index-4と同じことを行います。

12
T.J. Crowder

あなたはマップを使うことができます:

const newImages = this.state.images
  .map((image, index) => index === 4 ? updatedImage : image)
7
CD..

これが私の自己説明のノンライナーです

 const wantedIndex = 4;
 const oldArray = state.posts; // example

 const updated = {
     ...oldArray[wantedIndex], 
     read: !oldArray[wantedIndex].read // attributes to change...
 } 

 const before = oldArray.slice(0, wantedIndex); 
 const after = oldArray.slice(wantedIndex + 1);

 const menu = [
     ...before,  
     updated,
     ...after
 ]
2
webmaster

@Bardia Rastinソリューションを参照しましたが、ソリューションのインデックス値に誤りがあることがわかりました(インデックス3のアイテムは置き換えられますが、インデックス3のアイテムは置き換えられません)。

インデックス値、インデックスを持つアイテムを置き換える場合、答えは

_this.setState({images: [...this.state.images.slice(0, index), updatedImage, ...this.state.images.slice(index + 1)]})
_

this.state.images.slice(0, index)は新しい配列で、アイテムの開始がありますからインデックス-1まで(インデックスは含まれません)

this.state.images.slice(index)は、index以降から始まる項目を持つ新しい配列です。

インデックス4のアイテムを正しく置き換えるには、答えは次のようになります。

_this.setState({images: [...this.state.images.slice(0, 4), updatedImage, ...this.state.images.slice(5)]})
_
1
V-SHY