【JavaScript】重複を含む配列を、各要素の出現回数を持つオブジェクト配列に変換する方法
例えば、次のように重複した要素を含む文字列の配列があるとします。
const arr = ['California','Texas','Texas','Texas','New York','Missouri','New Mexico','California'];
ここで求められるのは、このような配列を受け取るJavaScript関数を作成することです。作成する関数は、元の配列に含まれる一意な(ユニークな)要素ごとに1つのオブジェクトを生成し、それぞれのオブジェクトに出現回数を表す「count」プロパティを持たせた配列を返す必要があります。
したがって、上記の配列を渡した場合の最終的な出力は、次のようになります。
const output = [
{'name':'California', 'count':2},
{'name':'Texas', 'count':3},
{'name':'New York', 'count':1},
{'name':'Missouri', 'count':1},
{'name':'New Mexico', 'count':1}
];実装例
まずは、forEachとfindIndexを組み合わせた基本的な実装方法を見てみましょう。
const arr = ['California','Texas','Texas','Texas','New York','Missouri','New Mexico','California'];
const findOccurrences = (arr = []) => {
const res = [];
arr.forEach(el => {
// 結果配列の中に同名のオブジェクトが存在するか確認
const index = res.findIndex(obj => {
return obj['name'] === el;
});
if(index === -1){
// 存在しなければ新規オブジェクトとして追加
res.push({
"name": el,
"count": 1
})
}
else{
// 存在していればカウントを増やす
res[index]["count"]++;
};
});
return res;
};
console.log(findOccurrences(arr));このコードの仕組みは以下の通りです。
- forEach:元の配列の各要素を先頭から順に処理します。
- findIndex:結果用の配列resの中に、同じ名前(nameプロパティ)を持つオブジェクトがすでに存在するかどうかを調べます。
- 見つからない場合(index === -1)は、新しく{name, count: 1}というオブジェクトを追加します。
- すでに存在する場合は、該当オブジェクトのcountプロパティを1ずつ加算していきます。
出力結果
コンソールには次のように表示されます。
[
{ name: 'California', count: 2 },
{ name: 'Texas', count: 3 },
{ name: 'New York', count: 1 },
{ name: 'Missouri', count: 1 },
{ name: 'New Mexico', count: 1 }
]補足:reduceを使ったより効率的な書き方
上記の方法は直感的で分かりやすい反面、要素ごとに毎回findIndexを実行するため、配列のサイズが大きくなると計算量がO(n²)に増えてパフォーマンスが低下する可能性があります。
データ量が多いケースでは、一度オブジェクト(ハッシュマップ)で集計してから整形する、reduceを使った方法が効率的です。
const findOccurrences = (arr = []) =>
Object.entries(
arr.reduce((map, el) => {
map[el] = (map[el] || 0) + 1;
return map;
}, {})
).map(([name, count]) => ({ name, count }));
console.log(findOccurrences(arr));この方法では、最初のreduceで{要素名: 出現回数}の形式のオブジェクトを1回の走査(O(n))で作成し、その後にObject.entriesとmapで目的の形状に変換しています。大量のデータを扱う場合にも高速に動作するため、実務ではこちらのアプローチが推奨されます。
-
JavaScriptで配列内の重複する値を見つける・削除する方法
JavaScriptで配列を扱っていると、同じ値が複数含まれているケースに遭遇することがあります。この記事では、配列から重複する値を検出・削除する方法を、初心者にもわかりやすくサンプルコード付きで解説します。 方法1:オブジェクトを使って重複を削除する もっとも古典的な手法のひとつが、空のオブジェクトをキーの記録用として使い、配列の各要素を順番に登録していく方法です。オブジェクトのキーは自動的に一意になるため、結果的に重複のない配列を作れます。 サンプルコード <html> <body> <script> function removeDuplicate
-
【JavaScript】配列内のネストされたオブジェクトの値を合計する方法
この記事では、JavaScriptを使って、配列内にネストされた(入れ子構造の)オブジェクトの値を合計する方法を解説します。サンプルコードでは、JSONデータの複数階層に格納された数値(costNum)を順番に取り出し、その合計をブラウザ上に表示します。 コード例 <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=d