概要
Javascriptのコーディング練習中に、配列内部のオブジェクトのプロパティ名を変えて新規オブジェクトを作る方法につまづいたので、備忘録も兼ねて記事にまとめます。
問題
ユーザーの情報が管理されている配列UserDataを、nameプロパティをキーに、valueプロパティを値に持つオブジェクトへ変換する関数を作成しましょう。
// 元の配列
const userData = [
{ name: "username", value: "Yamada" },
{ name: "email", value: "Yamada@test.com" },
{ name: "age", value: 25}
];
// 変換後のオブジェクト
{ username: "Yamada", email: "Yamada@test.com", age: 25 }
reduce関数を使った実装
今回はreduce()関数を使って、配列内のオブジェクトのデータを用いて新しくオブジェクトを生成するように記述しました。
reduce()関数は配列の各要素に対して、定義した「コールバック関数」を順番に適用します。
reduce(callbackFn, initialValue)
なお、callbackFnの戻り値は以下の4つです。
-
accumulator
前回のコールバック関数の呼び出し結果の値です。初回の呼び出しではinitialValue
が指定されていた場合はその値、そうでない場合はarray[0]の値が返ります。 -
currentValue
現在の要素の値です。初回の呼び出しではinitialValue
が指定された場合はarray[0]の値が返り、そうでない場合はarray[1]の値が返却されます。 -
currentIndex
現在のcurrentValue
のインデックスです。初回の呼び出しでは、initialValue
が指定された場合は0、そうでない場合は1になります。 -
array
reduce()が呼び出された配列です。
完成コード
上記を踏まえ、以下のプログラムを作成しました。
完成系のコードは以下です。
const userData = [
{ name: "username", value: "Yamada" },
{ name: "email", value: "Yamada@test.com" },
{ name: "age", value: 25}
];
const transformFormData = (data) =>
data.reduce((acc, cur) => {
acc[cur.name] = cur.value
return acc;
}, {});
console.log(transformFormData(userData));
initialValue
には初期値として空のオブジェクトを渡しました。
初回のコールバック関数で、この空のオブジェクトに対して、配列userDataの1つ目のオブジェクト{ name: "username", value: "Yamada" }
のnameプロパティを指定し、value値を格納しています。
これをuserData内の要素分だけ繰り返すことで、別名のプロパティ名で新規オブジェクトの作成ができるようになりました。
別解
色々調べていくと、スプレッド構文を使ってオブジェクト生成するとより記述もすっきりした記述ができそうです。
const userData = [
{ name: "username", value: "Yamada" },
{ name: "email", value: "Yamada@test.com" },
{ name: "age", value: 25}
];
const transformFormData = (data) =>
data.reduce((acc, cur) => ({...acc, [cur.name]: cur.value}), {});
console.log(transformFormData(userData));
この記載をする際は、プロパティ名が変数の値によって変わる動的プロパティとなるのでプロパティ名を[]
で囲まないとSyntax error
が生じるので注意です。