teratail header banner
teratail header banner
質問するログイン新規登録
JavaScript

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

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

2回答

838閲覧

複数の連想配列を一つの連想配列に変換したいです

sho.cat

総合スコア5

JavaScript

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

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

2クリップ

投稿2022/04/01 07:46

編集2022/04/01 13:06

0

2

前提

TypeScriptで連想配列を操作しようと考えています。
複数の連想配列(今回は2つ)を結合したいと考えております。

実現したいこと 

objHeaderとobjBodyをgroup()で結合して
resultに変換をしたいです。

TypeScript

1objHeader: any[] = [ 2 { rank: '1位', point: 40, group: 1 }, 3 { rank: '2位', point: 20, group: 2 }, 4 ]; 5 6 objBody: any[] = [ 7 { rank: '1位', point: 40, group: 1 }, 8 { rank: '2位', point: 30, group: 1 }, 9 { rank: '3位', point: 20, group: 1 }, 10 { rank: '1位', point: 50, group: 2 }, 11 { rank: '2位', point: 20, group: 2 }, 12 { rank: '3位', point: 10, group: 2 }, 13 ]; 14 15result: any[] = [ 16 { 17 rank: '1位', 18 point: 40, 19 group: 1, 20 data: [ 21 { rank: '1位', point: 40, group: 1 }, 22 { rank: '2位', point: 30, group: 1 }, 23 { rank: '3位', point: 20, group: 1 }, 24 ], 25 }, 26 { 27 rank: '2位', 28 point: 50, 29 gr: 2, 30 data: [ 31 { rank: '1位', point: 50, group: 2 }, 32 { rank: '2位', point: 20, group: 2 }, 33 { rank: '3位', point: 10, group: 2 }, 34 ], 35 },

試したこと

map関数を使用して作ろうと考えましたが、上手くいきませんでした。。。

Typescript

1 this.objBody.map((value: any) => { 2 this.objHeader.map((value2: any) => { 3 if (value.group === value2.group) { 4   value2.data = value 5 } 6 }); 7 });

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

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

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

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

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

miyabi_takatsuk

2022/04/01 08:02

うまくいかなかったとは、具体的にどういった結果だったのでしょうか? (想定のオブジェクトにならなかった、エラーが出たなど)
sho.cat

2022/04/01 08:31 編集

申し訳ありません。書き方が悪かったです。 上手くいかなかったというより、試したことにあるソース部分までは書いたのですが、 そこから先がどう操作してよいか分らなくなってしまいました。 作成中は下記のように書いたのですが、mapで回る度dataが上書きされるのでどうしてよいかわからなくなってしまいました。 ``` this.objBody.map((value: any) => { this.objHeader.map((value2: any) => { if (value.gr === value2.gr) { value2.data = value } }); }); ```
miyabi_takatsuk

2022/04/01 08:34

そのif文の中身まで書きましょう。 質問本文は修正できますので。 やりたいこと、何が違うのかわかりましたので、回答に移ります。
guest

回答2

0

Array.prototype.groupBy() がもうすぐメジャーブラウザで使えるようになりそうなので、こちらを使うがいいかと思います。

ts詳しくないので、バニラですが、サンプルを置いておきます。
https://jsfiddle.net/Lhankor_Mhy/2jtn5ae8/

js

1 const groupBy = objBody.groupBy(({ group }) => group) 2 const result = objHeader.map(x => { 3 x.data = groupBy[x.group] 4 return x 5 })

polyfill :
https://github.com/zloirock/core-js
https://cdn.jsdelivr.net/npm/core-js-bundle@3.21.1/index.min.js


Array.prototype.groupBy() - JavaScript | MDN
Array grouping - Chrome Platform Status

投稿2022/04/01 08:52

Lhankor_Mhy

総合スコア37488

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

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

miyabi_takatsuk

2022/04/01 09:12

こんな便利なメソッド出てたとは・・・。 早く標準になってほしいですね。
Lhankor_Mhy

2022/04/01 09:18

Chrome Platform Status によると、Webkit も Shippng となっていたので、数年の内には行けそうな気がしますね。
sho.cat

2022/04/01 13:05

ご返信ありがとうございます。 groupBy関数は知りませんでした。 少しロジックが難しいですが、理解しようと思います。 ありがとうございました!
guest

0

ベストアンサー

そのまま代入をしてしまうと、元のオブジェクトに代入、となってしまいますので、
それでは、質問者さんの想定の挙動にはならないでしょう。

まず、型を定義した方が、進めやすいかと思いますので、型を定義し処理をしていきましょう。

typescript

1interface Data { 2 rank: string; 3 point: number; 4 group: number; 5} 6 7interface DataWrapper extends Data { 8 data: Data[]; 9}

次に、変数を、型を使った宣言に直します。

typescript

1objHeader: Data[] = [ 2 // 省略 3]; 4 5objBody: Data[] = [ 6 // 省略 7]; 8

では実処理です。
オブジェクトのプロパティに代入すると、上書きされてしまうので、
mapループ上で新たなオブジェクトを作り、mapから返すようにしましょう。

javascript

1const result: DataWrapper[] = this.objHeader.map((value: Data) => { 2 // 最終で統合したいのは、Headerが基準となるため、一次ループは、Header 3 // 分割代入でコピる 4 const obj: DataWrapper = {...value, data: []}; 5 this.objBody.forEach((value2: Data) => { 6 // 二次ループは、Bodyの方で行う 7 if (value.group === value2.group) { 8 // 新しく作ったオブジェクトの方に追加する 9 obj.data.push(value2); 10 } 11 }); 12 return obj; 13});

もっと、短くできるかもしれませんが。

うまくいかなければコメントください。

投稿2022/04/01 09:09

miyabi_takatsuk

総合スコア9559

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

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

sho.cat

2022/04/01 13:04

ご返信ありがとうございます。 まずは説明不足だったことをお許しください。 上書きされてしまって困っていた所解決することができました。 ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.30%

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

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

質問する

関連した質問