筆者は毎週だいたい 18 回くらいは JSON データを扱うことがあると思います。それでもまだ、目的に合わせてデータを操作する方法をほぼ毎回 Google で検索しています。その答えが常に見つかるような究極のガイドがあれば良いと思いませんか?
この記事では、JavaScript でオブジェクトの配列を操作するための基本を紹介します。
JSON 形式のデータを使用したことがあれば、JavaScript オブジェクトを使用したことがあると言えるでしょう。JSON とは JavaScript Object Notation の略です。
オブジェクトの作成はとてもシンプルです。次のように書くだけです。
{
"color": "purple",
"type": "minivan",
"registration": new Date('2012-02-03'),
"capacity": 7
}
上記のオブジェクトは車を表現しています。車にはさまざまな種類や色があり、各オブジェクトは特定の車を表します。

さて、多くの場合、このようなデータを外部のサービスから取得します。しかし、オブジェクトとその配列を自身で作成することもあるでしょう。筆者がこのオンラインショップを作成した時もそうでした。

このカテゴリー一覧の各アイテムが、HTML で書くと下記のようになっていると考えてみてください。

このコードを 12 回繰り返して書きたくはありませんでした。メンテナンスが困難になるからです。
オブジェクトの配列を作成する
では車の例に戻りましょう。この車のセットを見てください。

これは、次のように配列で表現することができます。
let cars = [
{
"color": "purple",
"type": "minivan",
"registration": new Date('2017-01-03'),
"capacity": 7
},
{
"color": "red",
"type": "station wagon",
"registration": new Date('2018-03-03'),
"capacity": 5
},
{
...
},
...
]
オブジェクトの配列は、ずっと同じ状態とは限りません。ほとんどの場合、何かしらの操作をする必要が出てきます。では、既存の配列にオブジェクトを追加する方法を見てみましょう。
オブジェクトを最初に追加する - Array.unshift

配列の最初の位置にオブジェクトを追加するには、Array.unshift
を使用します。
let car = {
"color": "red",
"type": "cabrio",
"registration": new Date('2016-05-02'),
"capacity": 2
}
cars.unshift(car);
オブジェクトを最後に追加する - Array.push

配列の最後の位置にオブジェクトを追加するには、Array.push
を使用します。
let car = {
"color": "red",
"type": "cabrio",
"registration": new Date('2016-05-02'),
"capacity": 2
}
cars.push(car);
オブジェクトを途中に追加する - Array.splice

配列の途中の位置にオブジェクトを追加するには、Array.splice
を使用します。この関数はアイテムを取り除くこともできるため、とても便利です。引数の取り方には少し注意が必要かもしれません。
Array.splice(
{変更の開始位置のインデックス},
{取り除くアイテムの数},
{追加するアイテム}
);
したがって、赤いフォルクスワーゲンのカブリオ (Cabrio、オープンカー) を 5 番目の位置に追加したい場合には、次のようになります。
let car = {
"color": "red",
"type": "cabrio",
"registration": new Date('2016-05-02'),
"capacity": 2
}
cars.splice(4, 0, car);
オブジェクトの配列をループして操作する
ここで質問があります。あなたはなぜオブジェクトの配列をループしたいのでしょうか?
なぜそのようなことを聞くかというと、ループすること自体が最終的に達成したい目的であることはほとんどないからです。
JavaScript では、ループを使って自分でロジックを実装しなくても問題を解決できるように多くの関数が用意されています。では見ていきましょう。
配列内のオブジェクトを値で検索する - Array.find
例として、赤い車を見つけたいとしましょう。そのためには Array.find
という関数を使うことができます。

let car = cars.find(car => car.color === "red");
この関数は最初に一致した要素を 1 つ返します。
console.log(car);
// 出力:
// {
// color: 'red',
// type: 'station wagon',
// registration: 'Sat Mar 03 2018 01:00:00 GMT+0100 (GMT+01:00)',
// capacity: 5
// }
また、複数の値を条件にして検索することもできます。
let car = cars.find(car => car.color === "red" && car.type === "cabrio");
この例では配列内の最後の車が取得されます。
配列から条件に当てはまる複数のオブジェクトを取得する - Array.filter
Array.find
関数はオブジェクトを 1 つだけ返す関数でした。赤い車をすべて取得したい場合には Array.filter
を使う必要があります。

let redCars = cars.filter(car => car.color === "red");
console.log(redCars);
// 出力:
// [
// {
// color: 'red',
// type: 'station wagon',
// registration: 'Sat Mar 03 2018 01:00:00 GMT+0100 (GMT+01:00)',
// capacity: 5
// },
// {
// color: 'red',
// type: 'cabrio',
// registration: 'Sat Mar 03 2012 01:00:00 GMT+0100 (GMT+01:00)',
// capacity: 2
// }
// ]
配列内のオブジェクトを変換する - Array.map
これはよく必要になる操作です。あるオブジェクトの配列を異なるオブジェクトの配列へと変換します。これは Array.map
の役割です。では、車をサイズに基づいて 3 つのグループに分類する例を考えましょう。

let sizes = cars.map(car => {
if (car.capacity <= 3){
return "small";
}
if (car.capacity <= 5){
return "medium";
}
return "large";
});
console.log(sizes);
// 出力:
// ['large','medium','medium', ..., 'small']
サイズ以外の値も必要であれば、新しいオブジェクトを作成することも可能です。
let carsProperties = cars.map(car => {
let properties = {
"capacity": car.capacity,
"size": "large"
};
if (car.capacity <= 5){
properties['size'] = "medium";
}
if (car.capacity <= 3){
properties['size'] = "small";
}
return properties;
});
console.log(carsProperties);
// 出力:
// [
// { capacity: 7, size: 'large' },
// { capacity: 5, size: 'medium' },
// { capacity: 5, size: 'medium' },
// { capacity: 2, size: 'small' },
// ...
// ]
配列内の全オブジェクトにプロパティを追加する - Array.forEach
では、車にサイズの情報を追加したい場合はどうしますか?その場合、元のオブジェクトに新しいプロパティ size
を追加して拡張できます。これは Array.forEach
関数が役に立つ場面です。
cars.forEach(car => {
car['size'] = "large";
if (car.capacity <= 5){
car['size'] = "medium";
}
if (car.capacity <= 3){
car['size'] = "small";
}
});
配列をプロパティでソートする - Array.sort
オブジェクトの変換が完了したら、次はオブジェクトを何らかの方法で並べ替えたいことがよくあります。
ソートは通常、すべてのオブジェクトが持っているプロパティの値に基づいて行います。ソートには Array.sort
関数が使用できますが、並べ替えのメカニズムを定義する関数を用意する必要があります。
例えば車を定員 (capacity) に基づいて降順に並べ替えたいとしましょう。

let sortedCars = cars.sort((c1, c2) => (c1.capacity < c2.capacity) ? 1 : (c1.capacity > c2.capacity) ? -1 : 0);
console.log(sortedCars);
// 出力:
// [
// {
// color: 'purple',
// type: 'minivan',
// registration: 'Wed Feb 01 2017 00:00:00 GMT+0100 (GMT+01:00)',
// capacity: 7
// },
// {
// color: 'red',
// type: 'station wagon',
// registration: 'Sat Mar 03 2018 01:00:00 GMT+0100 (GMT+01:00)',
// capacity: 5
// },
// ...
// ]
Array.sort
は、2 つのオブジェクトを比較し、もし並べ替え用の関数の実行結果が正の数であれば、1 番目のオブジェクトを 2 番目の位置に動かします。つまり、並べ替え用の関数は「1 番目のオブジェクトを 2 番目に配置すべきですか?」という質問だと考えることができます。

不要な位置交換を避けるために、両方のオブジェクトの値が同じだった場合を示す 0 (ゼロ) のケースを加えることを忘れないでください。
配列内のオブジェクトが条件を満たすかチェックする - Array.every, Array.some
Array.every
と Array.some
は、各オブジェクトが特定の条件を満たすかのチェックだけを行いたい場合に便利です。
例えば、配列内に赤いカブリオがあるでしょうか?すべての車に最低 4 人が乗車できるでしょうか?もっとウェブに関連した例で言うと、ショッピングカート内に特定の製品があるでしょうか?
cars.some(car => car.color === "red" && car.type === "cabrio");
// 出力: true
cars.every(car => car.capacity >= 4);
// 出力: false
もしかしたら、Array.some
によく似た関数の Array.includes
を覚えているかもしれません。しかし、Array.includes
はプリミティブ型の配列でのみ動作します。
まとめ
この記事では、オブジェクトの配列を作成、操作、変換、ループする基本的な関数について説明しました。つまずきがちなケースのほとんどをカバーしているはずです。
より高度な機能を必要とするユースケースがあれば、こちらの配列についての詳細なガイド (英語) や W3Schools のリファレンス (英語) を参照してください。
または筆者にご連絡ください。また別の記事を用意します :-)