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

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

ただいまの
回答率

87.79%

JSONで取得した値を比較表形式で出力したい。

解決済

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 2,472

score 44

前提・実現したいこと

JavaScriptにてJSONのデータを受取ってテーブルを生成したいと考えております。
テーブルの形式としては少しイレギュラーで、見出しを1行目に置くのではなく1列目に
見出し項目を置きたいと考えております。

形式としては以下の通りとなります。(いわゆる比較表みたいな感じです。)

1個目 2個目 3個目
見出1 値1-1 値2-1 値3-1
見出2 値1-2 値2-2 値3-2
見出3 値1-3 値2-3 値3-3
見出4 値1-4 値2-4 値3-4

HTMLのソースとしては以下の様なものを吐き出せないかと考えております。

<table border="1">
  <tr>
    <th></th><th>1個目</th><th>2個目</th><th>3個目</th>
  </tr>
 <tr>
    <td>見出1</td><td>値1-1</td><td>値2-1</td><td>値3-1</td>
  </tr>
 <tr>
    <td>見出2</td><td>値2-1</td><td>値2-2</td><td>値3-2</td>
  </tr>
 <tr>
    <td>見出3</td><td>値1-3</td><td>値2-3</td><td>値3-3</td>
  </tr>
 <tr>
    <td>見出4</td><td>値1-4</td><td>値2-4</td><td>値3-4</td>
  </tr>
</table>

JSONを取ってくるところは何とかなりそうなのですが、1行目の出力以降をどう処理すればいいか分かりません。
JQueryとか使う方法もあるとは思うのですが、ライブラリの依存などを避けたいのでなるべくピュアJavaScriptで実現できればと考えております。
すいませんが、解決方法をご教示いただけますでしょうか。

該当のソースコード

function sample(){
    var json =[
            {"midashi1":"val11","midashi2":"val12","midashi3":"val13","midashi4":"val14"},
            {"midashi1":"val21","midashi2":"val32","midashi3":"val23","midashi4":"val24"},
            {"midashi1":"val31","midashi2":"val32","midashi3":"val33","midashi4":"val24"}
    ];

        var msg = JSON.stringify(json);
        var t = JSON.parse(msg);
        var keys = Object.keys(t);
    var rs = '<table border="1">'
    for(var i=0, l=keys.length; i<l; i++){
        //ここをどう記述すればいいかわからない
        console.log(t[keys[i]].midashi1);
        console.log(t[keys[i]].midashi2);
        console.log(t[keys[i]].midashi3);
        console.log(t[keys[i]].midashi4);
    }
    rs +='</table>';
    document.getElementById('darea').innerHTML = rs;
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • Otazoman

    2019/01/22 18:32

    色々とご指摘ありがとうございます。勉強になります。
    mts10806様
    JQueryの件、理解不足ですいませんでした。バージョンが色々とあると読込が必要なのでてっきり依存するものかと思っていました。
    miyabi-sun様
    型に関しての理解が弱くてすいません。JavaScriptのオブジェクトと配列の区別も今一つ綺麗にできていないです。全部、ひとまず配列的なものというような乱暴な理解なので、きちんとそれぞれに区別がある点をもっとしっかり勉強しないといけないですね。[];で囲ってあるのは配列、{}はJavaScrptのオブジェクトという理解です。まだまだ精進せねばです。

    キャンセル

  • miyabi-sun

    2019/01/22 18:42

    あー、そういう感じのものじゃないです。

    例えばCSV(カンマ セパレート バリュー)ってありますよね、カンマ区切りの二次元データ形式です。
    こいつはファイルから読み出した時は単なる文字列でしかありません。
    「改行文字やカンマという特殊文字でこの単なる文字列を切り離した上で二次元配列に加工してロードする手順」をパースと呼びますが、
    このパースという一手間を加えて初めて二次元配列として扱えるデータになります。
    なのでCSVファイル自体は単なる文字列、専用のルールに沿って書かれているだけのね。

    JSONもCSVファイルと同じく単なる文字列です。
    文字列にしなきゃ保存出来ないしネットワーク通信で送受信出来ませんからね。
    これをJavaScriptで扱えるデータ形式と同じ書き方なんだという思想で解析して、
    読み取って初めてJavaScript世界で使える値に変身するのです。

    キャンセル

  • Otazoman

    2019/01/22 18:52

    おおっ、そうだったんですね。ありがとうございます。

    キャンセル

回答 3

+5

for文のネストで二重ループを作れば解決出来るでしょう。
適宜<tr>で挟まなければならないので、もう少し複雑になりますが、この方向で考えてください。

// Object.keys(t)にすると、[0, 1, 2]という誰得配列になるので、0番目の要素をサンプルとしてキー情報を抜き出す
var keys = Object.keys(t[0]);
for (var i = 0; i < keys.length; i++) {
  var key = keys[i];
  for (var j = 0; j < t.length; j++) {
    var value = t[j][key];
    rs += '<td>' + value + '</td>';
  }
}

ただまぁ、下記のような機能を覚えればスマートに書けるので余裕が出てきたら
配列を操作するメソッドの扱いも勉強してみてください。

ES2015という新しいバージョンの書き方はIE11には非対応ですので、
もし気になるようならBabelのような新しいバージョンのコードをES5相当の書き方にコンパイルするツールや、そこの部分だけES5相当の書き方で代用することを検討してみてください。
下記のコードは可読性重視でフル活用しています。

var t = [
  {"midashi1":"val11","midashi2":"val12","midashi3":"val13","midashi4":"val14"},
  {"midashi1":"val21","midashi2":"val32","midashi3":"val23","midashi4":"val24"},
  {"midashi1":"val31","midashi2":"val32","midashi3":"val33","midashi4":"val24"}
];
var keys = Object.keys(t[0]);

var rs = `<table>
  <thead>
    <tr>
      <th></th>
      ${t.map((_, i) => `<th>${i + 1}個目</th>`).join('\n')}
    </tr>
  </thead>
  <tbody>
    ${keys.map(key => `<tr><td>${key}</td>${
      t.map(it => `<td>${it[key]}</td>`).join('')
    }</tr>`).join('\n')}
  </tbody>
</table>`;

console.log(rs);
// "<table>
//   <thead>
//     <tr>
//       <th></th>
//       <th>1個目</th>
// <th>2個目</th>
// <th>3個目</th>
//     </tr>
//   </thead>
//   <tbody>
//     <tr><td>midashi1</td><td>val11</td><td>val21</td><td>val31</td></tr>
// <tr><td>midashi2</td><td>val12</td><td>val32</td><td>val32</td></tr>
// <tr><td>midashi3</td><td>val13</td><td>val23</td><td>val33</td></tr>
// <tr><td>midashi4</td><td>val14</td><td>val24</td><td>val24</td></tr>
//   </tbody>
// </table>"

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/01/22 18:40

    ご回答ありがとうございます。今回はmatherさんの方法がシンプルだったのでそちらを採用させていただきました。コードがすごく読みやすくて、ぜひ使いたいと思うのですが、まだまだ理解が追い付いていないので精進しないといけないと感じています。
    リンク先の内容もしっかり理解できるように頑張りたいと考えております。
    色々とありがとうございました。

    キャンセル

checkベストアンサー

+3

行と列を取り替える方法もあります。

var result = {};
json.forEach(x => 
  Object.keys(x).forEach( k => {
    if(k in result) {
      result[k].push(x[k]);
    } else {
      result[k] = [x[k]];
    }
  })
);

これを実行すると次のような値になります。

{
  "midashi1": [
    "val11",
    "val21",
    "val31"
  ],
  "midashi2": [
    "val12",
    "val32",
    "val32"
  ],
  "midashi3": [
    "val13",
    "val23",
    "val33"
  ],
  "midashi4": [
    "val14",
    "val24",
    "val24"
  ]
}

HTMLの表現にする箇所はご自身で考えてください。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/01/22 16:35

    あー、先に値を整形して、後はfor文で回すだけにするってのも上等手段ですよね。
    今回のケースは初期のデータが形式が悪いので、
    無理に二重ループでこねくり回すよりこっちの方が良さそうですね。

    キャンセル

  • 2019/01/22 18:37 編集

    ありがとうございます。アドバイスの方法でうまく動きました。(IE11では構文エラーで動かないので、こちらの対策はまた調べます。)
    HTMLの書き出しに関してはぶさいくな書き方ですが、以下の様にしのぎました。

    var rs = '<table id="petinsuranceResult" border="1">';
    +'<tr>'
    +'<th></th><th>1個目</th><th>2個目</th><th>3個目</th><th>4個目</th>'
    +'</tr>';
    +'<tr>'
    +'<td>項目名</td>'
    for(var i=0;i<recCount;i++){
    rs +='<td>'
    + result.midashi[i]
    +'</td>'
    }
    rs +='</tr>'
    rs +='</table>'
    document.getElementById('darea').innerHTML = rs;

    キャンセル

  • 2019/01/22 18:45

    構文エラーはES2015という新しいJavaScreiptの仕様で追加されたアロー関数ですね。
    少々長くなりますが普通の無名関数定義でいけるので、
    アロー関数に関して調査しながら無名関数へ書き換えてみてください。

    キャンセル

+1

<!DOCTYPE html>
<title></title>
<meta charset="utf-8">

<style>
table tr:first-of-type {
  background: rgba(255,255,0,.5);
}
table tr td:first-of-type {
  background: rgba(0,255,255,.4);

}
</style>

<body>

<script>
let json = [
  {"midashi1":"val11","midashi2":"val12","midashi3":"val13","midashi4":"val14"},
  {"midashi1":"val21","midashi2":"val32","midashi3":"val23","midashi4":"val24"},
  {"midashi1":"val31","midashi2":"val32","midashi3":"val33","midashi4":"val24"}
];


let
  a = Object.keys (json[0]),
  b = [['', ...json.map ((_, a) => 1 + a + '個目')], ...a.map (a => [a, ...json.map (b => b[a])])],
  table = document.body.appendChild (document.createElement ('table')), tr;
  table.setAttribute ('border', 1);

  b.forEach (
    a => (tr = table.insertRow (-1), a).forEach (
      a => tr.insertCell (-1).textContent = a));
</script>

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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

関連した質問

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