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

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

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

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

Q&A

解決済

2回答

692閲覧

javascript 複雑な配列での多重ループについて

mmsan1110

総合スコア2

JavaScript

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

0グッド

0クリップ

投稿2022/12/06 13:50

編集2022/12/06 18:12

前提

javascriptで複雑な配列を多重ループで処理するコードを書いているのですが、
多重ループの処理で躓いており想定している結果とならないのでお知恵をお貸しいただけないでしょうか。

実現したいこと

リスト(aaa)の配列から多階層(bbb)となっている配列と一致しているidを取得し、
一致している配列のstrをリストの配列(aaa)へ書き込むコードを作成予定です。

試したこと

//idをidNameへ変更 var aaa = [{name : "aa",idName1: 'aa01' }, {name : "bb",idName1: 'aa17'}, {name : "cc",idName1: 'aa08a'}, {name : "dd",idName1: 'aa01' }, {name : "ee",idName1: 'aa02' }, {name : "ff",idName1: 'aa05' }, {name : "gg",idName1: 'aa09' }]; //idをidNameへ変更,strをNumへ変更,code追加 var bbb = {hoge01 : { hoge02 : { hoge3 : { hoge4 : [ {hoge5 : [ {hoge6: [{hoge7: [{idName: 'aa01' ,code:0,Num : 1}]}]}, {hoge6: [{hoge7: [{idName: 'aa02' ,code:0,Num : 2}]}, {hoge7: [{idName: 'aa03' ,code:0,Num : 3}]}]}],}, {hoge5 : [ {hoge6 : [{hoge7: [{idName: 'aa04' ,code:0,Num : 4}]}, {hoge7: [{idName: 'aa05' ,code:0,Num : 5}]}, {hoge7: [{idName: 'aa06' ,code:0,Num : 6}]}, {hoge7: [{idName: 'aa07' ,code:0,Num : 7}]}, {hoge7: [{idName: 'aa08' ,code:0,Num : 8}]}, {hoge7: [{idName: 'aa09' ,code:0,Num : 9}]}, {hoge7: [{idName: 'aa10' ,code:0,Num : 10}]}]}]}, {hoge5 : [ {hoge6 : [{hoge7: [{idName: 'aa11' ,code:0,Num : 11}]}, {hoge7: [{idName: 'aa012' ,code:0,Num : 12}]}]}]}]}}}}; //mapで試しconsole.logで確認したが思った結果とならなかった。 bbb.hoge01.hoge02.hoge3.hoge4.map(hoge4 => hoge4.hoge5.map(hoge5 => hoge5.hoge6.map(hoge6 => hoge6.hoge7.map(hoge7 => console.log(aaa.map(aaa =>aaa.idName1).indexOf(hoge7.idName)) ) ) ) ); //欲しい結果 var aaa = [{name : "aa",idName1: 'aa01',Num : 1}, {name : "bb",idName1: 'aa17',Num :''},//一致しない場合はなし {name : "cc",idName1: 'aa08a',Num : 8}, {name : "dd",idName1: 'aa01',Num : 1}, {name : "ee",idName1: 'aa02',Num : 2}, {name : "ff",idName1: 'aa05',Num : 5}, {name : "gg",idName1: 'aa09',Num : 9}];

map関数で深層のhoge7を一つ一つ拾い上げることはできたのでhoge7.map上に
aaaのmap関数を記載しIndexOfで検索をすることができると考えていたのですが、
どうしても、bbbが基準となってしまいます。
aaa.mapとbbb.mapを個々で書きindexOfで比較できればなと調べたのですが、それも分からずじまいでした。
このような、複雑な配列はmap等を使わずにhoge7内を一つ一つ拾い上げることは可能なのでしょうか。
ご教示頂けると幸いです。

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

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

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

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

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

mmsan1110

2022/12/06 17:02

修正いたしました。
guest

回答2

0

ベストアンサー

オブジェクトを再帰処理する関数を一つ作っておくと便利です

javascript

1const a = 2 [{name : "aa",idName1: 'aa01' }, 3 {name : "bb",idName1: 'aa17'}, 4 {name : "cc",idName1: 'aa08a'}, 5 {name : "dd",idName1: 'aa01' }, 6 {name : "ee",idName1: 'aa02' }, 7 {name : "ff",idName1: 'aa05' }, 8 {name : "gg",idName1: 'aa09' }]; 9 10const b = 11{hoge01 : { 12hoge02 : { 13hoge3 : { 14hoge4 : [ 15 {hoge5 : [ 16 {hoge6: [{hoge7: [{idName: 'aa01' ,code:0,Num : 1}]}]}, 17 {hoge6: [{hoge7: [{idName: 'aa02' ,code:0,Num : 2}]}, 18 {hoge7: [{idName: 'aa03' ,code:0,Num : 3}]}]}],}, 19 {hoge5 : [ 20 {hoge6 : [{hoge7: [{idName: 'aa04' ,code:0,Num : 4}]}, 21 {hoge7: [{idName: 'aa05' ,code:0,Num : 5}]}, 22 {hoge7: [{idName: 'aa06' ,code:0,Num : 6}]}, 23 {hoge7: [{idName: 'aa07' ,code:0,Num : 7}]}, 24 {hoge7: [{idName: 'aa08' ,code:0,Num : 8}]}, 25 {hoge7: [{idName: 'aa09' ,code:0,Num : 9}]}, 26 {hoge7: [{idName: 'aa10' ,code:0,Num : 10}]}]}]}, 27 {hoge5 : [ 28 {hoge6 : [{hoge7: [{idName: 'aa11' ,code:0,Num : 11}]}, 29 {hoge7: [{idName: 'aa012' ,code:0,Num : 12}]}]}]}]}}}}; 30const getAllValuesWithObject=obj=>{ 31 let ret=[]; 32 Object.entries(obj).forEach(ent=>{ 33 ret=ret.concat( 34 ent[1] instanceof Object? 35 getAllValuesWithObject(ent[1],ent[1]): 36 [ent.concat(obj)] 37 ); 38 }); 39 return ret; 40}; 41const Nums=getAllValuesWithObject(b).filter(x=>x[0]=="idName").reduce((x,y)=>(x[y[1]]=y[2].Num,x),{}); 42a.forEach(x=>x.Num=Nums[x.idName1]??''); 43console.log(a);

投稿2022/12/07 04:17

yambejp

総合スコア114839

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

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

mmsan1110

2022/12/07 14:44

回答ありがとうございます。 こちらのコードで無事動作いたしました、 まだ理解していないところがあるので、じっくり解読したいと思います。 また、機会があればよろしくお願いいたします。
guest

0

1.JSONと正規表現を使った方法

とりあえず、idName と code と Numが隣接していて常にこの順番で並んでいるという前提になりますが、

js

1const json = JSON.stringify(bbb); 2const re = /"idName":"(.+?)","code".+?,"Num":(\d+)/gm; 3const table = {}; 4 5for (let p; p = re.exec(json);) { 6 table[p[1]] = p[2]; 7} 8 9aaa = aaa.map(e => ({ ...e, "Num" : table[e.idName] ?? '' })); 10console.log(aaa)

2.再帰を使った方法

こちらは順番に依存しません。(読みやすさの観点からあえて reduce等 は使っていません)

js

1const table = {}; 2 3function scan(obj) { 4 if (obj instanceof Array) { 5 obj.forEach(e => scan(e)); 6 } else { 7 Object.keys(obj).forEach(p => { 8 if (p == 'idName' && obj.hasOwnProperty('Num')) { 9 table[obj['idName']] = obj['Num']; 10 } 11 12 if (obj[p] instanceof Object || obj[p] instanceof Array) { 13 scan(obj[p]); 14 } 15 }); 16 } 17} 18 19scan(bbb); 20aaa = aaa.map(e => ({ ...e, "Num" : table[e.idName] ?? '' })); 21console.log(aaa);

投稿2022/12/06 14:44

編集2022/12/06 22:08
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

mmsan1110

2022/12/06 15:54

回答ありがとうございます。 条件がある想定をしていなかったので、実際の配列に近いものに修正いたしました。申し訳ありません。 idとstrは隣り合っておらず、codeを挟んだ形となっております。 また、idは数値ではなく文字列になっています。 この場合どのような形になるのでしょうか。お手数おかけしますが、よろしくお願いいたします。
mmsan1110

2022/12/07 14:43

再度回答いただきありがとうございます。 今回、色々なコードの書き方があることを学ばせていただきました。 また、機会があればよろしくお願いいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問