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

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

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

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

Q&A

解決済

3回答

1122閲覧

配列の値が、 オブジェクトの中にどのくらいあるかを返したい

gksh7

総合スコア40

JavaScript

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

0グッド

1クリップ

投稿2018/07/18 23:06

前提・実現したいこと

配列(arr)の中に含まれている一つ一つの値が、
オブジェクト(obj)の中にどのくらい含まれているか、その数を返したいと思っています。

該当のソースコード

const arr = [hoge, fuga, piyo] const obj = {   "tasks": [     { "id": 1, "item": “piyo” },     { "id": 2, "item": “hoge” },     { "id": 3, "item": “piyo” },     { "id": 4, "item": “fuga” },     { "id": 5, "item": “hoge” },     { "id": 6, "item": “piyo” } ] } // ↓↓↓ // 期待する戻り値 // hoge: 2 // fuga: 1 // piyo: 3

返される値は、オブジェクトでもなんでもいいのですが
たとえば、 {hoge:2, fuga:1, piyo:3}

この個数を出すには、JavaScriptをどう組むのがスマートなのでしょうか?
(underscore等のライブラリは、訳あって使えないので、 ネイティブのJsで組みたいと思っています)

ヒントだけでもご教示いただけますと助かります。
何卒宜しくお願いたします。

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

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

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

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

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

guest

回答3

0

ベストアンサー

js

1const r = obj.tasks.reduce((o, t) => { 2 o[t.item] = o[t.item] + 1 || 1 3 return o 4}, {}) 5 6// or 7 8const r2 = {} 9obj.tasks.forEach(t => { 10 r2[t.item] = r2[t.item] + 1 || 1 11})

投稿2018/07/18 23:47

sii_side

総合スコア849

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

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

gksh7

2018/07/19 00:08

ありがとうございます。 forEachの方で実現できました! とても短くかけるんですね! コードも理解できました。 ※reduce の方は、やってみてはいないのですが、  このような関数があることを初めて知ったので、(はずかしながら)これから調べてみます! やりたいことが実現できましたので、御礼申し上げます。 どうもありがとうございました。
guest

0

こんにちは。

sii_side さんのご回答にある reduce を使い、さらに結果として得られるオブジェクトとして、Map を使うことにすると、MapsetメソッドがレシーバのMapオブジェクトを返してくれることを利用して、以下のように、reduce の第1引数に渡す関数本体で returnが不要になります。

[jun68ykt@macbook ~]$ node -v

v9.6.1
[jun68ykt@macbook ~]$ cat tera136707.js

javascript

1const obj = { 2 tasks: [ 3 { id: 1, item: 'piyo' }, 4 { id: 2, item: 'hoge' }, 5 { id: 3, item: 'piyo' }, 6 { id: 4, item: 'fuga' }, 7 { id: 5, item: 'hoge' }, 8 { id: 6, item: 'piyo' } 9 ] 10}; 11 12const counts = obj.tasks.reduce( 13 (m, t) => m.set(t.item, (m.get(t.item) || 0) + 1), 14 new Map() 15); 16 17console.log(counts);

[jun68ykt@macbook ~]$ node tera136707.js

Map { 'piyo' => 3, 'hoge' => 2, 'fuga' => 1 }
[jun68ykt@macbook ~]$

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


追記

コメントから頂戴した、以下の質問に回答します。

●質問 => このアローが入ってきているのは、そういう仕様だということしょうか? piyoがkeyで、値が3という認識で合っていますでしょうか?

まず、

piyoがkeyで、値が3という認識で合っていますでしょうか?

については、はい、その認識で合ってます。

次に

=> このアローが入ってきているのは、そういう仕様だということしょうか?

については、そういう実装になっている、という解釈のほうがよいです。
より詳しくは、私の回答では node v9.6.1 でJSを実行したものなので、

node v9.6.1 では Mapオブジェクトを console.log で出力すると、 Map { 'piyo' => 3, 'hoge' => 2, 'fuga' => 1 } という風に、キーと値の対応を => を使った形式で出力するように、 console.log が作られている。

と考えたほうがよいです。
というのも、他の JavaScriptの実行環境(=わかりやすくいうと、他の場所で動くJavaScript)の中には、Mapオブジェクトをconsole.log で出力したときに、キーと値との対応を => ではない記号で表しているものも、あり得るからです。

例えば、以下のようなJSを含むHTMLを作ります。

html

1<!DOCTYPE html> 2<html lang="ja"> 3<head> 4 <meta charset="UTF-8"> 5 <title>Q136707</title> 6 <script> 7 document.addEventListener("DOMContentLoaded", function(event) { 8 const obj = { 9 tasks: [ 10 { id: 1, item: 'piyo' }, 11 { id: 2, item: 'hoge' }, 12 { id: 3, item: 'piyo' }, 13 { id: 4, item: 'fuga' }, 14 { id: 5, item: 'hoge' }, 15 { id: 6, item: 'piyo' } 16 ] 17 }; 18 19 const counts = obj.tasks.reduce( 20 (m, t) => m.set(t.item, (m.get(t.item) || 0) + 1), 21 new Map() 22 ); 23 24 console.log(counts); 25 }); 26 </script> 27</head> 28<body> 29 30</body> 31</html>

そして、上記HTMLをMac版Firefox の最新バージョン(v61.0.1)で表示し、開発ツールを開いたところが以下です。

イメージ説明

上記で分かるとおり、=> ではなく、 が使われているので、

Mac版Firefox の最新バージョン(v61.0.1)に組み込まれたJavaScript処理系では、 Mapオブジェクトを console.log で表示すると、 Map(3) { piyo → 3, hoge → 2, fuga → 1 } と表示するように、 console.log が作られている。

と言えます。

余談ですが、マップや連想配列やハッシュといった、キーと値の組を持つデータ構造を、(表示するときではなく)プログラムの中で定義するのに、 => を使う言語があります。
たとえばRubyでは

ruby

1counts = { 'piyo'=>3, 'hoge'=>2, 'fuga'=>1 }

と書きますし、PHPでは以下です。

php

1$counts = [ 'piyo'=>3, 'hoge'=>2, 'fuga'=>1 ];

ですので、 JavaScript で Mapオブジェクトを console.log で出力したとき
=> が使われるのは、RubyやPHPを知っている人にとっては、自然な(というか見慣れた)
感じがすることでしょう。

投稿2018/07/19 02:13

編集2018/07/19 13:07
jun68ykt

総合スコア9058

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

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

gksh7

2018/07/19 03:06

ご親切にありがとうございます。 さらに、一つ勉強になりました。 そして大変参考になりました。 mapって、setとかgetとかもできるんですね。 自分の方でも試してみて、同様に下記で生成されました。 それで、大変恐縮ですが、一つ追加で質問をさせてください。 基本的なことをお伺いしまして申し訳ございません。 'piyo' => 3 というように、一つ一つが左記の表示になっていますが ●質問 => このアローが入ってきているのは、そういう仕様だということしょうか? piyoがkeyで、値が3という認識で合っていますでしょうか? よろしければ、ご教示いただけますと幸いです。 何卒宜しくお願いたします。
jun68ykt

2018/07/19 12:28

> そして大変参考になりました。 とのことでよかったです! > ●質問 への返答を、回答欄のほうに追記しました。参考になれば幸いです。
gksh7

2018/07/19 23:06

詳細なご説明をありがとうございました。 質問のご回答だけでなく、それに付随する情報まで(かつ、具体的なソースまで)ご親切に教えていただきまして、大変感謝申し上げます。 そして、=> についてはブラウザのconsole.logによって違うんですね。 console.logによって異なるなんて、そうゆうことがあるんだ…と、 とても不思議な気がしました。 他の言語では自然な感じに感じられる記法なんですね。 これも面白い情報でした。 たくさんの有益な情報を本当にありがとうございました。 まだまだ初級者ですので、今後も学んでいきます! フォローさせていただきますね。 今後もどうぞ宜しくお願いいたします。
guest

0

単純にループを回してカウントして行ってはいかがですか?

そういうのは質問者さんが言う「スマート」ではないから NG と言うことでしたら、その辺りをもう少し詳しく説明ください。

投稿2018/07/18 23:17

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

gksh7

2018/07/18 23:37

ありがとうございます。 説明が足らずに申し訳ございません。 >ループして、カウントして… おっしゃる通りにやりたいと思います!! 一応、forEachとifでマッチしたら、カウントする…ってところまでは行けそうです。 ありがとうございます。 ただ、arrの値に何がはいってくるのか、また、いくつ入ってくるのか、分からないことがありまして… その場合の組み方に頭を悩ませていました。 説明下手で恐縮ですが、うまく伝わりますでしょうか? 何卒宜しくお願いたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問