[JavaScript] JSON データを簡易なフォーマットに変換したい

こんにちは、広野です。

React アプリを書いていると、JSON データから使用しないデータを差っ引いて、後々処理しやすいデータフォーマットに変換したくなるときがあります。

簡単な例ですが、JavaScript にもいろいろな書き方があって面白かったので、紹介します。

やりたいこと

アプリ内で、左側の JSON データを右側のフォーマットのデータに変換したい。

実現方法

以下の Array (配列) に使用できるメソッドを使用します。

Array.prototype.map() - JavaScript | MDN
map() メソッドは、与えられた関数を配列のすべての要素に対して呼び出し、その結果からなる新しい配列を生成します。
Array.prototype.forEach() - JavaScript | MDN
forEach() メソッドは、与えられた関数を、配列の各要素に対して一度ずつ実行します。
Array.prototype.push() - JavaScript | MDN
push() メソッドは、配列の末尾に 1 つ以上の要素を追加することができます。また戻り値として新しい配列の要素数を返します。

map メソッド、forEach メソッドともに、配列内の各要素に対して同じ処理を繰り返し実行するものです。forEach メソッドを使用するときは push メソッドも併用します。

以下の 2 つの例は、いずれも目的を達成できます。json_before が変換前、json_after が変換後のデータだと思ってください。

map メソッドを使ったシンプルな例

let json_after = json_before.map(row => {
  return {
    "name": row.name,
    "email": row.attributes[0].email
  }
});

この書き方では、json_before の各要素を row 変数に格納し、その row を使いつつ { } 内に記述した処理を繰り返し実行します。実行した結果を配列として返してくれるので、それを json_after で受け取ります。ここでは、return でダイレクトに編集済み JSON を返すようにしています。

無駄のないシンプルな書き方です。

forEach + push メソッドを使った例

let json_after = [];
json_before.forEach(row => {
  json_after.push(
    {
      "name": row.name,
      "email": row.attributes[0].email
    }
  );
});

この書き方では、map と同じように json_before の各要素を row 変数に格納し、その row を使いつつ { } 内に記述した処理を繰り返し実行します。map とは違い、実行した結果を配列として返してくれません。そのため、編集した JSON を json_after 配列に格納するために push メソッドを使います。push メソッドは、要素を配列の最後尾に追記してくれるものです。当然、push メソッドは配列にしか利かないので、あらかじめ json_after 変数を配列として定義(let json_after = [];) しておく必要があります。

map メソッドに比べると複雑です。

他にも、書き方のパターンとしては以下 2 つの観点でも書き方が異なるので、書き方の組み合わせパターンは本当に様々です。

  • (row => { の部分をアロー関数ではなく function で書く
  • 配列の定義に new Array() を使う

map メソッドの NG な例

今回、最後に配列に格納された JSON データを必要とする処理が目的だったため、map メソッドの方がシンプルで良さげでした。しかし、配列を戻さずに命令して終わりのようなコードを繰り返し実行させる場合は、forEach メソッドの使用が推奨されています。

以下は map メソッドの NG な例です。動きますが、無駄があります。

json_before.map(row => {
  alert(row.name + "のメールアドレスは" + row.attributes[0].email + "です。");
});

map メソッドは結果を配列にして返すのですが、返した結果を変数で受け取っていませんし、受け取ったとしても使われないデータです。単純に alert でポップアップメッセージを表示しているだけのコードですので。

この目的の場合は、以下のように forEach メソッドで書くべきです。alert を連発させるのは例として現実的ではないかもしれませんが説明のため、ご容赦ください。

json_before.forEach(row => {
  alert(row.name + "のメールアドレスは" + row.attributes[0].email + "です。");
});

まとめ

いかがでしたでしょうか?

JSON データの変換と併せて、メソッドの使い分けも書きました。細かいことですが、なるべく効率の良いコードを書けるよう常に心掛けたいですね。

本記事が皆様のお役に立てれば幸いです。

著者について
広野 祐司

AWSサーバーレスアーキテクチャを駆使して社内クラウド人材育成アプリや教育コンテンツをつくっています。ReactでSPAを書き始めたら、快適すぎて他の開発言語には戻れなくなりました。AWSサーバーレスやReactの仲間を増やしたいです。
取得資格:AWS認定は7つ、ITサービスマネージャ、ITIL v3 Expert、等
2020, 2021 APN AWS Top Engineers 受賞
2022 AWS Partner Ambassador 受賞
好きなAWSサービス:AWS Amplify / Amazon Cognito / AWS Step Functions / AWS CloudFormation

広野 祐司をフォローする
クラウドに強いによるエンジニアブログです。
SCSKは専門性と豊富な実績を活かしたクラウドサービス USiZE(ユーサイズ)を提供しています。
USiZEサービスサイトでは、お客様のDX推進をワンストップで支援するサービスの詳細や導入事例を紹介しています。
その他技術ナレッジ
TechHarmony
タイトルとURLをコピーしました