1
2
お題は不問!Qiita Engineer Festa 2024で記事投稿!
Qiita Engineer Festa20242024年7月17日まで開催中!

げきむずデータも怖くない!JavaScriptのオブジェクト配列変換の方法

Posted at

はじめに

DBやAPIから取得したデータを扱う際、配列を別の配列にしたり、配列からオブジェクトを生成したり、ということがあるかと思います。

今回はオブジェクトの配列にフォーカスして、どのように別の配列やオブジェクトを生成するか、ということを確認します。

本記事内では「TypeScript」を扱っていますが、JavaScriptでも使えるメソッドになります。

オブジェクトの配列から、別の配列を生成する

概要

// ユーザー型の定義
interface User {
  id: number;
  name: string;
  email: string;
  age: number;
}
// ユーザーデータ
const users: User[] = [
  { id: 1, name: "田中太郎", email: "tanaka@example.com", age: 28 },
  { id: 2, name: "佐藤花子", email: "sato@example.com", age: 35 },
  { id: 3, name: "鈴木一郎", email: "suzuki@example.com", age: 42 },
];

上記のようなユーザーデータが格納された配列から、nameだけを取り出して、別の配列を生成する方法を考えます。

対応方法

配列から新しい配列を生成するには、mapメソッドを使用します。

const userNames: string[] = users.map((user) => user.name);

mapメソッドは引数として関数を受け取ります。
この関数は3つの引数を受け取りますが、ほとんどの場合1つめしか使いません。
そのため、2つめ、3つめの引数の役割については省略します。

引数の1つめは配列のデータです。ここではusersのデータ、つまりオブジェクトが一つずつ渡されます。

そして、関数の戻り値が新たな配列の値として設定されます。
ここではuser.nameを返しているので、新たに生成された配列userNamesuser.nameの配列となります。

今回は単純な処理ですが、もっと複雑に値を加工することもできます。

配列から配列を生成するときはmap、と覚えておきましょう。

オブジェクトの配列から、単一のオブジェクトを生成する

概要

以下のようなオブジェクトの配列を考えます。

// ユーザー型の定義
interface FunctionControl {
  id: number;
  functionName: string;
  enable_create: number;
  enable_read: number;
  enable_update: number;
  enable_delete: number;
}
// ユーザーデータ
const functionControls: FunctionControl[] = [
  {
    id: 1,
    functionName: "user",
    enable_create: 1,
    enable_read: 1,
    enable_update: 0,
    enable_delete: 0,
  },
  {
    id: 2,
    functionName: "item",
    enable_create: 0,
    enable_read: 1,
    enable_update: 1,
    enable_delete: 0,
  },
  {
    id: 3,
    functionName: "customer",
    enable_create: 0,
    enable_read: 1,
    enable_update: 1,
    enable_delete: 0,
  },
];

機能名(functionName)と、その機能において作成、読取、更新、削除を有効化するか、の設定値(enable_~の各項目)を持ちます。

このままだとcustomerenable_createを確認したい場合、少し不便です。

{
  customer: {
    enable_create: 0,
    enable_read: 1,
    enable_update: 1,
    enable_delete: 0,
  },
};

こんな形式のオブジェクトであれば、各機能ごとの有効化状況を簡単に取得できます。

対応方法

配列からオブジェクトなどの単一の要素を生成するにはreduceメソッドを使用します。

  const functionControlObj = functionControls.reduce((acc, curr) => {
    acc[curr["functionName"]] = {
      create: curr["enable_create"],
      read: curr["enable_read"],
      update: curr["enable_update"],
      delete: curr["enable_delete"],
    };
    return acc;
  }, {} as Record<string, Record<string, number>>);

reduceメソッドは第一引数に関数を、第二引数に初期値を設定します。
第一引数に設定する関数は、最大で4つの引数を受け取りますが、よく使うのは1つめと2つめです。
1つめの引数には、初期値から蓄積された値が設定されます。
2つめの引数には、配列の値が設定されます。

例えば、今回のデータで行くと、
まず初めのaccは初期値に設定した空のオブジェクト{}が設定されています。
そして、currにはfunctionControlsの1番目のオブジェクトが設定されています。

acc(空のオブジェクト)のプロパティとして、curr(1番目のオブジェクト)のfunctionNameを設定し、その値としてenable_~のオブジェクトを設定しました。

{
  customer: {
    create: 0,
    read: 1,
    update: 1,
    delete: 0,
  },
};

こんな感じのオブジェクトを生成して、accに設定しているということです。

これを繰り返すことで、

{
  customer: { create: 0, read: 1, update: 1, delete: 0 },
  item: { create: 0, read: 1, update: 1, delete: 0 },
  user: { create: 1, read: 1, update: 0, delete: 0 },
};

このようなオブジェクトを生成することができます。

配列から単一の要素を生成する際はreduceと覚えておきましょう。

まとめ

mapreduceを適切に使うことで、配列を扱いやすい形に加工することができます。
個人的にreduceは若干使いにくさを感じますが、慣れれば便利だなと思いました。

ほかにもfromEntriesを使う方法もあるのですが、それはまた別の機会に紹介します。

1
2
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
1
2