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

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

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

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

Q&A

解決済

2回答

842閲覧

求める配列を作りたいです

inukujira

総合スコア130

JavaScript

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

0グッド

1クリップ

投稿2020/05/19 10:59

すみません教えてください。
以下、配列の元となるデータがあります。

【加工前】

javascript

1const data = { 2 group: [ 3 { 4 uid:1001, 5 list: [ 6 { sensor_group_id: 117}, 7 { sensor_group_id: 118} 8 ] 9 }, 10 { 11 uid:1002, 12 list: [ 13  { sensor_group_id: 119}, 14  ] 15 }, 16 { 17 uid:1003, 18 list: [ 19  { sensor_group_id: 116}, 20  { sensor_group_id: 117}, 21  ] 22 }, 23 ] 24}

この配列を以下のような配列に作り直すためにはどのように実装すればよいでしょうか?

【加工後】

javascript

1const result = [ 2 { 3 sensor_group_id:116, 4 list:[1003] 5 }, 6 { 7 sensor_group_id:117, 8 list:[1001,1003] 9 }, 10 { 11 sensor_group_id:118, 12 list:[1001] 13 }, 14 { 15 sensor_group_id:119, 16 list:[119] 17 }, 18]

実装サンプルは以下です。

Stackblitz - Demo

mapを使って実装しようとしましたがコード量が非常に膨大になってしまうので
何か良い方法がありましたらご教示ください。

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

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

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

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

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

kei344

2020/05/19 11:05

ご自身で試されたコードを質問文に追記し、「何」が「どのように」わからないのか、コードのどの部分で詰まっているのかなどを具体的に追記されたほうが回答が望めると思います。
guest

回答2

0

ベストアンサー

こんにちは

いっぺんにやろうとすると大変そうなので、段階を踏んで加工していきます。

まず、以下にて sensor_group_iduid とのペアを要素とする配列を得ます。

javascript

1const pairs = data.group.map(x => 2 x.list.map(y => [y.sensor_group_id, x.uid]) 3).flat();

上記によって、 pairs には以下が得られます。

[[ 117, 1001 ], [ 118, 1001 ], [ 119, 1002 ], [ 116, 1003 ], [ 117, 1003 ]]

次に、pairs をソートします。

javascript

1pairs.sort((x1, x2) => x1[0] - x2[0] || x1[1] - x2[1]);

上記によって、 pairs は以下のようになります。

[[ 116, 1003 ], [ 117, 1001 ], [ 117, 1003 ], [ 118, 1001 ], [ 119, 1002 ]]

上記の pairs から以下によって result を得ることができます。

javascript

1const result = pairs.reduce((ary, [gid, uid], i) => { 2 const x = i > 0 ? ary[ary.length - 1] : null; 3 if (x && x.sensor_group_id === gid) { 4 x.list.push(uid); 5 } else { 6 ary.push({ sensor_group_id: gid, list: [uid] }); 7 } 8 return ary; 9}, []);

result は以下のようになります。

[ { sensor_group_id: 116, list: [ 1003 ] }, { sensor_group_id: 117, list: [ 1001, 1003 ] }, { sensor_group_id: 118, list: [ 1001 ] }, { sensor_group_id: 119, list: [ 1002 ] } ]

以上、参考になれば幸いです。

追記

別案です。同じ sensor_group_id ごとのグルーピングを行うために、lodash の _.groupBy を使います。

javascript

1const data = { 2 group: [ 3 { 4 uid: 1001, 5 list: [ 6 { sensor_group_id: 117 }, 7 { sensor_group_id: 118 } 8 ] 9 }, 10 { 11 uid: 1002, 12 list: [ 13  { sensor_group_id: 119 }, 14  ] 15 }, 16 { 17 uid: 1003, 18 list: [ 19  { sensor_group_id: 116 }, 20  { sensor_group_id: 117 }, 21  ] 22 }, 23 ] 24} 25 26const pairs = data.group.map(x => 27 x.list.map(y => [y.sensor_group_id, x.uid]) 28).flat(); 29 30console.log(pairs); 31 32const groups = _(pairs) 33 .groupBy(0) 34 .mapValues(v => v.map(x => x[1]).sort((x1, x2) => x1 - x2)) 35 .value(); 36 37console.log(groups); 38 39const result = Object.entries(groups) 40 .sort(([x1], [x2]) => x1 - x2) 41 .map(([x, y]) => ({ 42 sensor_group_id: +x, 43 list: y 44 })); 45 46console.log(result); 47 48 49

投稿2020/05/19 11:38

編集2020/05/20 00:10
jun68ykt

総合スコア9058

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

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

inukujira

2020/05/20 01:30

ありがとうございます! しかし、環境が古くてflatが使えずネストされている配列をフラットにすることができませんでした、、 node.jsのバージョンがver8.6で他社環境なんで変更できず、、大変厚かましいのですがflatを使わずにフラットする方法はございますでしょうか?
inukujira

2020/05/20 02:01

[].concatを使って実装できました。 jun68yktさんのコードを利用して求めてる配列ができましたのでお礼申し上げます。 ありがとうございました。
jun68ykt

2020/05/20 02:13

コメントありがとうございます。 > 大変厚かましいのですがflatを使わずにフラットする方法はございますでしょうか? flat メソッドでやっていることを自分で書けばよいかと思います。以下は、reduce を使ってフラットした配列を得る一例です。 https://codepen.io/jun68ykt/pen/zYvywwx?editors=0012 または、回答に追記した、 lodash を使うほうを採用されるのであれば、lodash にもフラットするメソッド https://lodash.com/docs/#flatten があるので、これを使って以下のようにもできます。 https://codepen.io/jun68ykt/pen/qBOLmPa?editors=0012
jun68ykt

2020/05/20 02:15

@AkitoshiManabeさん フォローありがとうございます。 @inukujiraさん あ、そうですね。concat 使ってもできますね。
guest

0

クラスを使って解こうと思いましたが、解り辛くなってしまいました。
一応 Map を使いました。ソートを考えてなかったので後から追加。

javascript

1const 2 KEY = 'sensor_group_id'; 3 KEY2 = 'uid'; 4 ARY = 'list'; 5 6 7class A { 8 constructor (a, ...b) { 9 this[KEY] = a; 10 this[ARY] = b; 11 } 12 13 add (a) { 14 this[ARY].push (a); 15 return this; 16 } 17} 18 19 20class B { 21 constructor () { 22 this.map = new Map; 23 } 24 25 add (a,b) { 26 this.map.set(a,(this.map.get(a)||new A(a)).add(b)); 27 return this; 28 } 29 30 order (a = false) { 31 this.map = [...this.map.keys ()] 32 .sort (a?(a,b)=>a===b?0:a<b:(a,b)=>a===b?0:b<a) 33 .reduce ((a,b)=>a.set(b,this.map.get(b)),new Map); 34 return this; 35 } 36} 37 38 39let r = data.group.reduce((b,{list:c,[KEY2]:d})=>c.reduce((b,e)=>b.add(e[KEY],d),b),new B); 40console.log (...r.order().map.values()); 41

投稿2020/05/19 16:26

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

inukujira

2020/05/20 02:02

one_lineさん回答ありがとうございました。 本件解決いたしましたのでお礼申し上げます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問