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

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

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

Electronは、HTML5とNode.jsというWebの技術を用いてデスクトップアプリケーションを作成できるクロスプラットフォームな実行環境です。

Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

JavaScript

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

Q&A

解決済

3回答

1539閲覧

多次元配列の特定のキーに対応する値をすべて抽出、加工したい

lg_rino

総合スコア19

Electron

Electronは、HTML5とNode.jsというWebの技術を用いてデスクトップアプリケーションを作成できるクロスプラットフォームな実行環境です。

Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

JavaScript

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

0グッド

1クリップ

投稿2019/04/22 07:44

electron-vueでアプリを作っています。

アプリ起動時に、NeDBからデータを配列に読み出した後、希望の形式に加工して表示したいです。
配列への読み出しまではできていますが、その後の抽出、加工がうまくいきません。

配列は以下のようなもので、

[ { groupName: 'グループ1', groupMakeDate: '2019/1/1', member: [ { firstName: '太郎', familyName: '山田', memo: 'メモ1' }, { firstName: '次郎', familyName: '山田', memo: 'メモ2' } ] }, { groupName: 'グループ2', groupMakeDate: '2019/2/2', member: [ { firstName: '花子', familyName: '佐藤', memo: 'メモ3' } ] }, { groupName: 'グループ3', groupMakeDate: '2019/3/3', member: [ { firstName: '太郎', familyName: '山田', memo: 'メモ4' }, { firstName: '花子', familyName: '佐藤', memo: 'メモ5' } ] } ]

これから、以下のようなグループ名+氏名だけの配列を抽出したいです。

[ "山田太郎", "山田次郎", "佐藤花子", "山田太郎", "佐藤花子" ]

NeDBからのデータ読み出しに引き続いて、以下のように書いてみましたが、配列の中身が空になってしまいます。

created: function () { this.$db.find({}, function (err, doc) { this.groupList = doc || [] this.memberName = this.groupList.map(function (val) { val['members'].map(function (val) { return val[0]['firstName'] }) }) }.bind(this)) },

mapを使うのも初めてで、だんだん混乱してきました。
そもそも、この配列を作るのが最終目的ではなく、以下のように名前ごとにデータをまとめて表示させたいのですが、この方法がよいのかもわからなくなってきました。

山田太郎  2019/1/1~ グループ1 メモ1  2019/3/3~ グループ3 メモ4 山田次郎  2019/1/1~ グループ1 メモ2 佐藤花子  2019/2/2~ グループ2 メモ3  2019/3/3~ グループ3 メモ5

名前だけの配列を作る方法、または、最終目的を実現するための道筋のヒント、どちらでもよいのでアドバイスをいただけないでしょうか。

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

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

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

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

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

guest

回答3

0

多分その軸で名前一覧作っても無駄というか、
そこから元データに向けてどうやって検索してメモとかグループ名引っ張ってくるねんという課題が残ります。
途方にくれちゃうんじゃないでしょうか?

という訳で一撃で質問文の最終目的の方に切り込みます。
この辺はパズルの世界ですね。
こういうデータ形式はよくありますが、超複雑で人間が扱えるように作ってはいません。

そして(私を含む)人間は頭が良くないので、あまり複雑なデータ形式は扱えません。
なので(私のような)お馬鹿さんでもわかるような簡素なデータに変換してから使いましょう。


Lodashは使えますか?
今回のケースではLodashのgroupByが超絶機能しますが、
ネイティブのJSにはそんなモノないので辛いですよ?
大丈夫ですか?

reduceを自在に操ってさらっと作れますか?
reduceは死ぬほど難解ですし、ある程度手足のように扱える様になっても面倒です。
是非Lodashを検討してみてください。


Lodashを使えるとするならこのような感じです。
一度名前と所属グループのオブジェクトの配列にしたほうが良いでしょう。
Online Lodash Testerで試してみましょう。

JavaScript

1var doc = []; // 質問文のコードをペタリ 2result = _.chain(doc || []) 3 .map(function(d){ 4 return d.member.map(function(member){ 5 return { 6 name: member.firstName + member.familyName, 7 memo: member.memo, 8 group: d.groupName, 9 make: d.groupMakeDate 10 } 11 }) 12 }) 13 .flatten() 14 .groupBy(function(it){ return it.name }) 15 .value();

結果はこうなります。

JSON

1{ 2 "太郎山田": [ 3 { 4 "name": "太郎山田", 5 "memo": "メモ1", 6 "group": "グループ1", 7 "make": "2019/1/1" 8 }, 9 { 10 "name": "太郎山田", 11 "memo": "メモ4", 12 "group": "グループ3", 13 "make": "2019/3/3" 14 } 15 ], 16 "次郎山田": [ 17 { 18 "name": "次郎山田", 19 "memo": "メモ2", 20 "group": "グループ1", 21 "make": "2019/1/1" 22 } 23 ], 24 "花子佐藤": [ 25 { 26 "name": "花子佐藤", 27 "memo": "メモ3", 28 "group": "グループ2", 29 "make": "2019/2/2" 30 }, 31 { 32 "name": "花子佐藤", 33 "memo": "メモ5", 34 "group": "グループ3", 35 "make": "2019/3/3" 36 } 37 ] 38}

Lodashならそこからeachなんかを被せればキーと値で実行出来るのでもう2〜3行足すだけで質問文の要望は達成できます。
楽勝ですね。


この考え方は素のJavaScriptでも応用出来ます。
しかし、JavaScriptにはflattenとgroupByがないので、
reduceを使って代用する必要があります。

この辺は課題として残しておきます。

まぁ無理しなくとも、二次元配列を2重のfor文で括ってえっちらおっちらやっても同じモノを作れると思いますが、
頭の体操がてら頑張ってみてくださいね。

投稿2019/04/22 08:20

編集2019/04/22 08:31
miyabi-sun

総合スコア21158

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

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

0

ベストアンサー

確かに頭の体操になった。
追記:ネイティブなJSだって短くなるよ。わざわざ2行にしたのだけれど・・・

html

1<!DOCTYPE html> 2<html lang="ja"> 3<meta charset="utf-8"> 4<title></title> 5<style> 6 7</style> 8<body> 9<dl></dl> 10 11<script> 12const data = [ 13 { 14 groupName: 'グループ1', 15 groupMakeDate: '2019/1/1', 16 member: [ 17 { 18 firstName: '太郎', 19 familyName: '山田', 20 memo: 'メモ1' 21 }, 22 { 23 firstName: '次郎', 24 familyName: '山田', 25 memo: 'メモ2' 26 } 27 ] 28 }, 29 { 30 groupName: 'グループ2', 31 groupMakeDate: '2019/2/2', 32 member: [ 33 { 34 firstName: '花子', 35 familyName: '佐藤', 36 memo: 'メモ3' 37 } 38 ] 39 }, 40 { 41 groupName: 'グループ3', 42 groupMakeDate: '2019/3/3', 43 member: [ 44 { 45 firstName: '太郎', 46 familyName: '山田', 47 memo: 'メモ4' 48 }, 49 { 50 firstName: '花子', 51 familyName: '佐藤', 52 memo: 'メモ5' 53 } 54 ] 55 } 56]; 57 58 59let map = data.reduce ((a,{groupName,groupMakeDate,member})=> 60 member.reduce ((a, {firstName, familyName, memo},c,d)=> 61 (c = familyName + firstName, d = [groupMakeDate, groupName, memo].join (' '), 62 a.set (c, a.has (c) ? [...a.get (c), d]: [d]), a), a) 63 ,new Map); 64 65document.querySelector ('dl').appendChild ( 66 [...map.entries ()].reduce ((a,[b,c])=> ( 67 a.appendChild (document.createElement ('dt')).textContent = b, 68 c.forEach (e=> a.appendChild (document.createElement ('dd')).textContent = e),a 69 ),document.createDocumentFragment ()) 70); 71 72 73</script> 74 75

投稿2019/04/22 08:41

編集2019/04/22 09:15
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

0

js

1val['members'].map(function (val) {

members -> member
return してない。

js

1return val[0]['firstName']

[0] は不要。

投稿2019/04/22 08:22

wtokuno

総合スコア448

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問