JavaScriptで1つのオブジェクトを人物ごとのオブジェクト配列に変換する方法
はじめに
JavaScriptでは、フラットなキーと値のペアで構成されたオブジェクトを、意味のあるまとまりごとのオブジェクト配列へ変換したいケースがよくあります。例えば「Person1_Age」「Person2_Height」のように、複数人分のデータが1つのオブジェクトに混在している場合、人物ごとにデータを分割して整理しておくと、後続の処理が格段に行いやすくなります。
問題の概要
次のような、複数人分の年齢・身長・体重のデータを持つオブジェクトを考えてみましょう。
const obj = {
Person1_Age: 22,
Person1_Height: 170,
Person1_Weight: 72,
Person2_Age: 27,
Person2_Height: 160,
Person2_Weight: 56
};
このオブジェクトを受け取り、同じ人物に関するデータを1つのオブジェクトにまとめ、それらを配列として返す関数を作成します。
期待される出力は次のとおりです。
const output = [
{
name: 'Person1',
age: 22,
height: 170,
weight: 72
},
{
name: 'Person2',
age: 27,
height: 160,
weight: 56
}
];
解決策
各キーを「_(アンダースコア)」で分割して人物名と属性名を取り出し、人物ごとにオブジェクトを生成しながら結果配列へ追加していきます。コードは以下のようになります。
const obj = {
Person1_Age: 22,
Person1_Height: 170,
Person1_Weight: 72,
Person2_Age: 27,
Person2_Height: 160,
Person2_Weight: 56
};
const separateOut = (obj = {}) => {
const res = [];
const map = {};
Object.keys(obj).forEach(el => {
// キーを「_」で分割し、人物名と属性名に分解する
const [person, info] = el.split('_');
// 初登場の人物なら、新しいオブジェクトを作成して配列に追加
if (!map[person]) {
map[person] = { name: person };
res.push(map[person]);
}
// 属性名は小文字に統一して値を代入
map[person][info.toLowerCase()] = obj[el];
});
return res;
};
console.log(separateOut(obj));
コードの解説
- Object.keys(obj):オブジェクトが持つすべてのキーを配列として取得します。
- el.split('_'):「Person1_Age」のようなキーを「Person1」と「Age」に分解します。
- map[person]:人物名をキーとした一時的なマップを用意することで、同じ人物に対しては既存のオブジェクトを再利用でき、重複した登録を防げます。
- info.toLowerCase():属性名を小文字に揃えることで、出力側のプロパティ名(age、height、weight)を統一しています。
なお、元のコードのように this を使う方法もありますが、アロー関数内での this の挙動は文脈によって変わるため、上記のように専用のマップオブジェクトを使う方が安全で読みやすい実装になります。
出力結果
コンソールには次のように表示されます。
[
{ name: 'Person1', age: 22, height: 170, weight: 72 },
{ name: 'Person2', age: 27, height: 160, weight: 56 }
]
まとめ
キー名が「人物名_属性名」という命名規則で統一されていれば、split() と forEach() を組み合わせるだけで、フラットなオブジェクトを構造化されたオブジェクト配列へ簡単に変換できます。より汎用的にしたい場合は reduce() を使う方法や、正規表現でキーを解析する方法も検討するとよいでしょう。状況に応じて最適な手法を選択してください。
-
JavaScriptのlengthプロパティで配列オブジェクトの長さを取得する方法
JavaScriptにおけるlengthプロパティとはJavaScriptのlengthプロパティは、文字列や配列などのオブジェクトが持つ要素数(サイズ)を返すために使用されます。配列の場合は格納されている要素の個数、文字列の場合は文字数を取得できます。ここでは、文字列と配列オブジェクトの長さをlengthプロパティで取得するサンプルコードを紹介します。サンプルコード以下の例では、ボタンをクリックすると配列の長さが画面に表示される仕組みを実装しています。<!DOCTYPE html> <html lang="ja"> <head> <
-
JavaScriptでオブジェクトの配列を1つのプレーンなオブジェクトにまとめる方法
JavaScriptでは、複数のオブジェクトに分かれたプロパティを、1つのプレーンなオブジェクト(単一のオブジェクト)に統合したい場面があります。本記事では、オブジェクトの配列を受け取って、その中に含まれるすべてのプロパティを1つのオブジェクトへ集約する方法を、サンプルコードとともにわかりやすく解説します。変換元となるデータ例として、次のように2つのオブジェクトを持つ配列を用意します。const arr = [{ name: Dinesh Lamba, age: 23, &n