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

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

ただいまの
回答率

88.81%

多次元配列から指定キーの配列を取得したい

解決済

回答 3

投稿

  • 評価
  • クリップ 1
  • VIEW 1,312

narutona

score 23

前提・実現したいこと

JavaScript、jQueryで、多次元配列から指定キーの配列を取得したいです。
宜しくお願い致します。

発生している問題・エラーメッセージ

「試したこと」にあるように、JavaScriptとjQueryと試した結果、以下のエラーとなります。

まずJavaScriptの方ではundefinedです。

undefined

そしてjQueryの場合のエラーは、日付の指定がわからずこちらです。

v['d{4}/d{2}'] is undefined

該当のソースコード

元になる配列です。
おおまかには、「月の下にidとuxが並ぶ」という構造です。
これを一番下の配列ごとに取得し、それぞれ「hoo()」をかけたいと思っています。

var array = {
  "postA":{
    "2019\/05":[
        {"id":1,"ux":a},
        {"id":2,"ux":b}
    ],
    "2019\/04":[
        {"id":3,"ux":c}
    ]
  },
  "postB":{
    "2019\/05":[
        {"id":4,"ux":d},
        {"id":5,"ux":e}
    ]
  }
};

function hoo(data){
    $('body').append('<p>'+data['id']+'</p>と<p>'+data['ux']+'</p>');
}

試したこと

以下、エラーの出るコートです。

まずJavaScriptでforを使ってみたのですが、上のように「undefined」となってしまいます。

for (let key in array) {
  for (let k in key) {
    const data = {
        id: k.id,
        ux: k.ux
    };
    hoo(data);
  }
}    


続いてjQueryのeachを使ってみたものの、不確定な日付をどう指定すればいいかわからず、正規表現を使ってみましたが上のエラーになってしまいました。

$.each(array, function(i, v) {
    const data = {
          id: v['\d{4}\/d{2}']['id'],
          ux: v['\d{4}\/d{2}']['ux']    
    };
    hoo(data);
});

補足情報(FW/ツールのバージョンなど)

「hoo()」がかかった状態として最終的に想定している出力は次のものです。
よろしければこの出力にすべく正しいソースコードをご教授願えませんでしょうか。

<p>1とa</p>
<p>2とb</p>
<p>3とc</p>
<p>4とd</p>
<p>5とe</p>
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 3

checkベストアンサー

+2

オブジェクトにarrayという変数名をつけるのは紛らわしいので
やめたほうがよいでしょう

<script>
$(function(){
  var obj = {
    "postA":{
      "2019/05":[
        {"id":1,"ux":"a"},
        {"id":2,"ux":"b"},
        ],
      "2019/04":[
        {"id":3,"ux":"c"},
        ],
    },
    "postB":{
      "2019/05":[
        {"id":4,"ux":"d"},
        {"id":5,"ux":"e"},
        ],
    },
  };
  Object.values(obj).forEach(x=>{
    Object.values(x).forEach(y=>{
      y.forEach(data=>{
        $('body').append('<p>'+data.id+'と'+data['ux']+'</p>');
      });
    });
  });
});
</script>

hooにわたす

hooに渡しても直に書いても同じです。
なお命題のhooはpタグが別れていて仕様がおかしいです
(pが別れていると補足情報のサンプルのようにはならない)

$(function(){
  var obj = {
    "postA":{
      "2019/05":[
        {"id":1,"ux":"a"},
        {"id":2,"ux":"b"},
        ],
      "2019/04":[
        {"id":3,"ux":"c"},
        ],
    },
    "postB":{
      "2019/05":[
        {"id":4,"ux":"d"},
        {"id":5,"ux":"e"},
        ],
    },
  };
  Object.values(obj).forEach(x=>{
    Object.values(x).forEach(y=>{
      y.forEach(data=>{
        hoo(data);
      });
    });
  });
});
function hoo(data){
    $('body').append('<p>'+data['id']+'と'+data['ux']+'</p>');
}

蛇足

  $.each(obj,(...x)=>{
    $.each(x[1],(...y)=>{
      y[1].forEach(hoo);
    });
  });

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/05/31 18:34 編集

    お世話になっております。
    蛇足は質問のレベルに降りてきてくださった感じでしょうか?
    教えて頂きたいのですが「...x」「...y」とはなんでしょうか?

    キャンセル

  • 2019/05/31 19:14

    var obj = ’・・・’
    という文字列になっているのでだめです
    仮にシングルクォートをとったとしても
    uxに指定しているa~eが変数として機能するのでおかしいです
    文字列リテラルとして捉えられるようにダブルクォートで囲んでください

    それも含めて私の回答のvar objのような書き方でお願いします

    キャンセル

  • 2019/05/31 20:12

    再度までありがとうございます!jsfiddleご覧になってくださったんですね。失礼かと思って消してしましました。なるほどシングルクオートのせいでオブジェクトではなくなっていたわけですか。ありがとうございました。

    キャンセル

+2

var array = {
  "postA":{
    "2019\/05":[
        {"id":1,"ux":"a"},
        {"id":2,"ux":"b"}
    ],
    "2019\/04":[
        {"id":3,"ux":"c"}
    ]
  },
  "postB":{
    "2019\/05":[
        {"id":4,"ux":"d"},
        {"id":5,"ux":"e"}
    ]
  }
};

Object.keys(array).reduce((a,c)=>a.concat(Object.keys(array[c]).flatMap(e=>array[c][e])),[]).forEach(hoo);

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/05/31 18:02

    複雑ってことですが何なら複雑じゃないのでしょうか。
    使える構文を縛ってください。それで書きますので。

    キャンセル

  • 2019/05/31 18:03

    ieは考えてないです。flatMapとか無理そうですし。

    キャンセル

  • 2019/05/31 18:30

    お気遣いありがとうございます。構文を縛るとしても「何で縛ると可能なのか」などがわからず。たとえるならマグロの釣り方を知りたいときに「どの釣り竿ならわかるの?」と聞かれ、「どの釣り竿ならマグロが釣れるのかわからない」といった感じです(笑)
    さらに現状としては結局自分の環境で実装できず、何がいけないのか再考していたりもするので、しばしお時間いただければと思います。

    キャンセル

+1

narutona様の習熟度に合わせてfor文のみで回答してみます。

元のコードの問題点は2箇所あります。

  1. for in で書くと、連想配列(オブジェクト)のキーを取得するだけなので、array[key]で値を取り出さないといけない。
  2. arrayの中身が3重構造になっているので、for文がもうひとつ必要。

arrayの3重目は通常の配列なので、for of が使えます(連想配列(オブジェクト)では使えない)。for in とは違い、値を直接取り出せるのでこちらを使うとよいです。

修正したコードは下の通りになります。

for (let id in array) {
  for (let month in array[id]) {
    for (let post of array[id][month]) {
      const data = {
        id: post.id,
        ux: post.ux
      };
      hoo(data);
    }
  }
}

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/05/31 20:11

    ざっと調べただけでは私のケースに完璧にあったご説明というのがなく、いつも半端な理解のままでした。頂戴したご説明のおかげでこれまで不明瞭だったいくつかの点がつながり目の前がすっきり晴れた気分です。どうもありがとうございます。感謝申し上げます。

    キャンセル

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

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

関連した質問

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