質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

2回答

808閲覧

javascriptの連想配列の中の子要素を、別の子要素形式の配列で上書きしたい

退会済みユーザー

退会済みユーザー

総合スコア0

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2021/07/28 10:28

編集2021/07/29 00:03

javascriptの連想配列の中の子要素を、別の子要素形式の配列で上書きしたいですが、うまくできなくて困っています。

javascript gridライブラリでセルの編集を使用しています。
不明点はjavascriptの配列の処理方法なので、gridのことは省略します。

■元データ(rowVersion列を追加)

javascript

1let currentRowData = [ 2 { 3 id: 1, name: "A", values: [ 4 { id: 1, parentId: 1, name: "a", value: 1 , rowVersion: "xxx" } 5 ] 6 } 7];

■ gridのセルをダブルクリックすると、childrenの入力を子画面で行います。
画面イメージ(ヘッダ追加)


name value
a □
b □
c □
[選択]


■ [選択]ボタンを押したとき、下記のscriptのような動きを想定していますが、うまくいかなく、どのように処理すれば良いでしょうか?
ただし、子画面で全てが入力しているとは限らないし、入力を消したものがnullになる場合もある。childrenのidが発行済みの場合もある。
※parentのidが0の時もありますが、それは質問の内容から省略します。

問題の原因はidがないものがあるのにfindを使っているので、もしかしたら
nameとvalue !== nullの2つの条件で取得しないといけないかもしれません。

javascript

1// 例①のデータを変更、parentのidが1の時とした場合 2let id = 1; 3 4// 元データ(rowVersion列を追加) 5let rowData = [ 6 { 7 id: 1, name: "A", values: [ 8 { id: 1, parentId: 1, name: "a", value: 1, rowVersion: "xxx"} 9 ] 10 } 11]; 12 13// 子画面で入力した変更データ(この入力データにrowVersion列はありません。) 14let values = [ 15 { id: 1, parentId: 1, name: "a", value: 1 }, 16 { id: 0, parentId: 1, name: "b", value: 4 }, 17 { id: 0, parentId: 1, name: "c", value: null } // これは入力していないデータ 18]; 19 20// childenのデータを更新 21const newRowData = rowData.map((currentValue) => { 22 // 例ではこのif文はid=1でtrueになります 23 if (currentValue.id === id) { 24 25 // valuesを、元データに上書きしたい 26 let childrens = values.map((currentValue2) => { 27 // 問題の原因はidがないからかも? 28 const newValue = currentRowData.values.find(({ id }) => currentValue2.id === id); 29 return newValue ?? currentValue2; 30 }, []); 31 32 currentValue2.values = childrens; 33 } 34 35 return currentValue; 36});

仕様追加しました。
・parentのidと、childrensのchildrenのparentIdは紐づいてます。
・childrensのidとrowVersion列は元のデータを利用、新しく入力したchildrensのchildrenで1つずつ入力箇所のみ、上書きしなければならない

(追記)
以下のようなコードを考えてみました。間違っている個所があるかもしれませんが。
少し冗長になってしまったかもしれません。

javascript

1let id = 1; 2 3let rowData = [ 4 { 5 id: 1, name: "A", values: [ 6 { id: 1, parentId: 1, name: "a", value: 1, rowVersion: "xxx"} 7 ] 8 } 9]; 10 11let values = [ 12 { id: 1, parentId: 1, name: "a", value: 1 }, 13 { id: 0, parentId: 1, name: "b", value: 4 }, 14 { id: 0, parentId: 1, name: "c", value: null } // これは入力していないデータ 15]; 16 17// childensのchildenでデータを更新 18const newRowData = rowData.map((currentValue) => { 19 // 例ではこのif文はid=1でtrueになります 20 if (currentValue.id === id) { 21 22 // valuesを、元データに上書きしたい 23 let childrens = values.map((currentValue2) => { 24 // find 25 let findChildren = currentValue.values.find((element) => { 26 return element.id === currentValue2.id && element.name === currentValue2.name; 27 }); 28 29 // newChildrenを準備、 findChildrenがあれば差し替え 30 let newChildren = { id: 0, parentId: id, name: null, value: null, rowVersion: null }; 31 findChildren ? (newChildren = findChildren) : null; 32 33 // newChildrenを更新 34 newChildren.name = currentValue2.name; 35 newChildren.value = currentValue2.value; 36 37 return newChildren; 38 }, []); 39 40 currentValue.values = childrens; 41 } 42 43 return currentValue; 44}, []);

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

追記にきました自己解決した方法になります。

javascript

1let id = 1; 2 3let rowData = [ 4 { 5 id: 1, name: "A", values: [ 6 { id: 1, parentId: 1, name: "a", value: 1, rowVersion: "xxx"} 7 ] 8 } 9]; 10 11let values = [ 12 { id: 1, parentId: 1, name: "a", value: 1 }, 13 { id: 0, parentId: 1, name: "b", value: 4 }, 14 { id: 0, parentId: 1, name: "c", value: null } // これは入力していないデータ 15]; 16 17// childensのchildenでデータを更新 18const newRowData = rowData.map((currentValue) => { 19 // 例ではこのif文はid=1でtrueになります 20 if (currentValue.id === id) { 21 22 // valuesを、元データに上書きしたい 23 let childrens = values.map((currentValue2) => { 24 // find 25 let findChildren = currentValue.values.find((element) => { 26 return element.id === currentValue2.id && element.name === currentValue2.name; 27 }); 28 29 // newChildrenを準備、 findChildrenがあれば差し替え 30 let newChildren = { id: 0, parentId: id, name: null, value: null, rowVersion: null }; 31 findChildren ? (newChildren = findChildren) : null; 32 33 // newChildrenを更新 34 newChildren.name = currentValue2.name; 35 newChildren.value = currentValue2.value; 36 37 return newChildren; 38 }, []); 39 40 currentValue.values = childrens; 41 } 42 43 return currentValue; 44}, []);

投稿2021/07/29 02:49

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

それぞれのidとparentIdの関係を把握しかねますが
事前にparentId?がわかっているなら、そのままvaluesに新しいvaluesを代入すれば良いように思います。

js

1const newRowData = rowData.map((currentValue) => { 2 3 // 例ではこのif文はid=1でtrueになります 4 if (currentValue.id === id) currentValue.values = values; 5 6 return currentValue; 7});

上書きしないデータ等をループで判別する必要があるなら、そのあたりの仕様の説明が必要かと思います。

投稿2021/07/28 12:47

編集2021/07/28 12:48
webgoto

総合スコア1293

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/07/28 23:29 編集

コメントありがとうございます。 単純にvaluesで上書きする方法はとれないです。 仕様の説明不足ですみませんが、仕様を追加しました。 ・rowVersion列を追加 ・parentのidと、childrensのchildrenのparentIdは紐づいてます。 ・childrensのidとrowVersion列は元のデータを利用、新しく入力したchildrensのchildrenで1つずつ入力箇所のみ、上書きしなければならない
webgoto

2021/07/29 01:13

提示頂いたコードでは現在、下記の値に上書きされていると思いますが、正しくはどのような値になる必要があるのでしょうか? values: Array (3) 0: {id: 1, parentId: 1, name: "a", value: 1, rowVersion: "xxx"} 1: {id: 0, parentId: 1, name: "b", value: 4, rowVersion: null} 2: {id: 0, parentId: 1, name: "c", value: null, rowVersion: null}
退会済みユーザー

退会済みユーザー

2021/07/29 02:04

現在、下記になっていますが、行き違いであればすみません。 values: Array (3) 0: {id: 1, parentId: 1, name: "a", value: 1 } 1: {id: 0, parentId: 1, name: "b", value: 4} 2: {id: 0, parentId: 1, name: "c", value: null }
webgoto

2021/07/29 02:11

すみません。その形になるのが正しいのですか?
退会済みユーザー

退会済みユーザー

2021/07/29 02:26 編集

説明わかりにくくてすみません、下記のフローを想定してます。 ■ 最初のデータ let rowData = [ { id: 1, name: "A", values: [ { id: 1, parentId: 1, name: "a", value: 1, rowVersion: "xxx"} ] } ]; ■ 入力データ let values = [ { id: 1, parentId: 1, name: "a", value: 1 }, { id: 0, parentId: 1, name: "b", value: 4 }, { id: 0, parentId: 1, name: "c", value: null } // これは入力していないデータ ]; ↓ rowDataのid=1のvaluesを入力データのvaluesで上書き ■ 結果データ rowData = [ { id: 1, name: "A", values: [ {id: 1, parentId: 1, name: "a", value: 1, rowVersion: "xxx"} {id: 0, parentId: 1, name: "b", value: 4, rowVersion: null} {id: 0, parentId: 1, name: "c", value: null, rowVersion: null} ] } ]
webgoto

2021/07/29 02:43

yuchan01様の記載されてるコードで既に結果データはそのようになっているように思いますが違う部分がありますでしょうか。
退会済みユーザー

退会済みユーザー

2021/07/29 02:48

追記のコードでうまくいきました。ありがとうございました。 一旦、自己解決とさせて頂きます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問