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

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

ただいまの
回答率

90.52%

  • JavaScript

    16389questions

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

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

解決済

回答 3

投稿

  • 評価
  • クリップ 1
  • VIEW 177

gksh7

score 10

 前提・実現したいこと

配列(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で組みたいと思っています)

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+4

const r = obj.tasks.reduce((o, t) => {
  o[t.item] = o[t.item] + 1 || 1
  return o
}, {})

// or 

const r2 = {}
obj.tasks.forEach(t => {
  r2[t.item] = r2[t.item] + 1 || 1
})

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/19 09:08

    ありがとうございます。
    forEachの方で実現できました!
    とても短くかけるんですね!
    コードも理解できました。

    ※reduce の方は、やってみてはいないのですが、
     このような関数があることを初めて知ったので、(はずかしながら)これから調べてみます!

    やりたいことが実現できましたので、御礼申し上げます。
    どうもありがとうございました。

    キャンセル

+3

こんにちは。

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

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

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' }
  ]
};

const counts = obj.tasks.reduce(
  (m, t) =>  m.set(t.item, (m.get(t.item) || 0) + 1),
  new Map()
);

console.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を作ります。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Q136707</title>
    <script>
      document.addEventListener("DOMContentLoaded", function(event) {
        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' }
          ]
        };

        const counts = obj.tasks.reduce(
          (m, t) =>  m.set(t.item, (m.get(t.item) || 0) + 1),
          new Map()
        );

        console.log(counts);
      });
    </script>
</head>
<body>

</body>
</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では

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

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

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

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

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/19 12:06

    ご親切にありがとうございます。
    さらに、一つ勉強になりました。
    そして大変参考になりました。

    mapって、setとかgetとかもできるんですね。

    自分の方でも試してみて、同様に下記で生成されました。

    それで、大変恐縮ですが、一つ追加で質問をさせてください。
    基本的なことをお伺いしまして申し訳ございません。

    'piyo' => 3 というように、一つ一つが左記の表示になっていますが

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

    よろしければ、ご教示いただけますと幸いです。
    何卒宜しくお願いたします。

    キャンセル

  • 2018/07/19 21:28

    > そして大変参考になりました。

    とのことでよかったです!

    > ●質問
    への返答を、回答欄のほうに追記しました。参考になれば幸いです。

    キャンセル

  • 2018/07/20 08:06

    詳細なご説明をありがとうございました。
    質問のご回答だけでなく、それに付随する情報まで(かつ、具体的なソースまで)ご親切に教えていただきまして、大変感謝申し上げます。

    そして、=> についてはブラウザのconsole.logによって違うんですね。
    console.logによって異なるなんて、そうゆうことがあるんだ…と、
    とても不思議な気がしました。

    他の言語では自然な感じに感じられる記法なんですね。
    これも面白い情報でした。

    たくさんの有益な情報を本当にありがとうございました。

    まだまだ初級者ですので、今後も学んでいきます!

    フォローさせていただきますね。
    今後もどうぞ宜しくお願いいたします。

    キャンセル

+1

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/19 08:37

    ありがとうございます。
    説明が足らずに申し訳ございません。

    >ループして、カウントして…
    おっしゃる通りにやりたいと思います!!
    一応、forEachとifでマッチしたら、カウントする…ってところまでは行けそうです。

    ありがとうございます。

    ただ、arrの値に何がはいってくるのか、また、いくつ入ってくるのか、分からないことがありまして…
    その場合の組み方に頭を悩ませていました。

    説明下手で恐縮ですが、うまく伝わりますでしょうか?

    何卒宜しくお願いたします。

    キャンセル

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

  • ただいまの回答率 90.52%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • JavaScript

    16389questions

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