3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【JavaScript】オブジェクト(連想配列)をObject.fromEntries()でmapする

Last updated at Posted at 2021-09-07

はじめに

オブジェクト(連想配列)をmapしたい場面があって調べたところObject.fromEntries()に出会った。
実際に動作を確認しながら使ってみたのでそのメモ。

簡単なサンプル

シンプルなオブジェクトをmapしてみる。

const obj = { a: 1, b: 2, c: 3 }

const convertedObj = Object.fromEntries(
  Object.entries(obj).map(([key, value]) => {
    console.log([key, value * 2])
    // コンソール出力
    // 1回目: ["a", 2]
    // 2回目: ["b", 4]
    // 3回目: ["c", 6]
    
    return [key, value * 2]
  }),
)

console.log(convertedObj)
// コンソール出力
// {a: 2, b: 4, c: 6}

なるほど、Object.fromEntries()の返り値がしっかり連想配列で返ってきてる。

今回実装した内容

想定場面

{ a: 数値、 b: "数値文字列", c: "日時(文字列)" }見たいな感じの配列↓↓をAPIからレスポンスで受け取って

const objArr = [
  { a: 10, b: "10", c: "2021-09-01T06:38:19.274406Z" },
  { a: 20, b: "20", c: "2021-09-02T06:38:19.274406Z" },
  { a: 30, b: "30", c: "2021-09-03T06:38:19.274406Z" },
  { a: 40, b: "40", c: "2021-09-04T06:38:19.274406Z" },
  { a: 50, b: "50", c: "2021-09-05T06:38:19.274406Z" },
];
  • a: 数値はそのままnumber型
  • b: "数値文字列"number型にキャスト
  • c: "日時"はそのままstring型
    こんな感じに↓↓整形したい場面があった。(普通はフロント側でこんな苦しい実装することも滅多にないと思いますが、、)
// 整形後(期待する結果)
[
{ a: 10, b: 10, c: "2021-09-01T06:38:19.274406Z" },
{ a: 20, b: 20, c: "2021-09-02T06:38:19.274406Z" },
{ a: 30, b: 30, c: "2021-09-03T06:38:19.274406Z" },
{ a: 40, b: 40, c: "2021-09-04T06:38:19.274406Z" },
{ a: 50, b: 50, c: "2021-09-05T06:38:19.274406Z" },
]

実装

冗長になってしまいました。でも、実現したいことはできた。

const objArr = [
  { a: 10, b: "10", c: "2021-09-01T06:38:19.274406Z" },
  { a: 20, b: "20", c: "2021-09-02T06:38:19.274406Z" },
  { a: 30, b: "30", c: "2021-09-03T06:38:19.274406Z" },
  { a: 40, b: "40", c: "2021-09-04T06:38:19.274406Z" },
  { a: 50, b: "50", c: "2021-09-05T06:38:19.274406Z" },
];

const convertedObjArr = objArr.map((obj) => {
  return Object.fromEntries(
    Object.entries(obj).map(([key, value]) => {
      // value を number型にキャストする
      const castedValue = Number(value);
      if (Number.isFinite(castedValue)) {
        console.log([key, castedValue]);
        // キャストに成功していれば、キャストした値をvalueとして返す
        return [key, castedValue];
      }
      console.log([key, value]);
      // キャストに失敗(NaN)すれば、そのままの値をvalueとして返す
      return [key, value];
    })
  );
});

console.log(convertedObjArr);

コンソールを確認

map内の処理結果

// value を number型にキャストする
const castedValue = Number(value);
console.log(castedValue);
if (Number.isFinite(castedValue)) {
  console.log([key, castedValue]);
  // キャストに成功していれば、キャストした値をvalueとして返す
  return [key, castedValue];
}
console.log([key, value]);
// キャストに失敗すれば、そのままの値をvalueとして返す
return [key, value];
コンソール出力
["a", 10]
["b", 10]
["c", "2021-09-01T06:38:19.274406Z"]
["a", 20]
["b", 20]
["c", "2021-09-02T06:38:19.274406Z"]
["a", 30]
["b", 30]
["c", "2021-09-03T06:38:19.274406Z"]
["a", 40]
["b", 40]
["c", "2021-09-04T06:38:19.274406Z"]
["a", 50]
["b", 50]
["c", "2021-09-05T06:38:19.274406Z"]

最終的な整形後の結果

 console.log(convertedObjArr);
コンソール出力
[
{a: 10, b: 10, c: "2021-09-01T06:38:19.274406Z"},
{a: 20, b: 20, c: "2021-09-02T06:38:19.274406Z"},
{a: 30, b: 30, c: "2021-09-03T06:38:19.274406Z"},
{a: 40, b: 40, c: "2021-09-04T06:38:19.274406Z"},
{a: 50, b: 50, c: "2021-09-05T06:38:19.274406Z"},
]

ちゃんと期待する結果が出力されました。
実際の実装ではreturn Object.fromEntries(以下を関数に切り出したものの、やはり冗長になってしまったので、もっと効率的な記述方法などあれば教えてください。

最後に

わかりやすい記事に非常に助けられました。
ありがとうございました。

JavaScript 面白い。

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?