オブジェクトを要素に持つ配列の追加・削除・更新 – JavaScript

本稿では、JavaScriptのオブジェクトを要素に持つ配列に対して、(1)新たなオブジェクトを追加する方法、(2)特定のオブジェクトを削除する方法、(3)特定のオブジュクトの内容を更新する方法をご紹介します。オブジュクトを持つ配列とは例えば下記のような配列で、本稿でも下記の例を用いて説明します。また、本稿ではReact等Webでの実践的な使用を想定し、各オブジュクトに固有のidを設定する方法、その他idを使った操作についても解説いたします。

const itemlist = [
{
id: 1,
rating: 5,
text: "The text of 1st item",
},
{
id: 2,
rating: 4,
text: "The text of 2nd item",
},
{
id: 3,
rating: 6,
text: "The text of 3rd item",
},
]

オブジュクトの追加

配列に新たなオブジェクトを追加するためには、まず、新たに追加するオブジュクトを作成します。本稿で想定するWebでは、例えばユーザーからのフォーム入力を受けて、下記のようなオブジュクトを作成したとします。

const newitem = {
rating: 7,
text: "The text of 4th item",
}

通常ユーザーからの入力にはidが付かないので、内部的にこのオブジェクトに新たな固有のidを付します。固有のidの生成をするライブラリーには様々なものがあると思いますが、ここではuuidを使用します。uuidをインポートの上、先ほど作成したnewitemオブジェクトにidを追加します。なおMongo DB、firestoreなど多くのDBでは自動でidを付与するのでこの操作は不要です。

import { v4 as uuidv4 } from "uuid";
newitem.id = uuidv4();

新たなnewitemオブジェクトを既存の配列itemlistに追加するためには、配列内で3つのドット…(スプレッド構文)を使用し、[新たに追加する要素, …元の配列]とします。

[newitem, ...itemlist]

オブジュクトの削除

配列から特定のオブジェクトを削除するためには、配列操作メソッドの1つであるfilter()を使用します。削除対象のオブジェクトを特定するために各オブジュクトが持つ固有のidを使用します。例えばWebでは、ユーザーがあるオブジェクトに係る削除ボタンを押すと、そのオブジェクトに紐づくidを取得できるとし、同idがここではid変数に格納されているとします。filterメソッドを使うと、配列内の各要素に対して、フィルターとなる条件を付して、同条件を満たす要素だけから構成される新たな配列を得ることができます。本件では削除対象以外の要素を残したいので、同条件をitem.id !== idとします。

itemlist.filter((item) => item.id !== id)

オブジェクト内の共通する要素の削除

特定のオブジェクトの削除ではなく、全てのオブジェクトから共通する要素を削除することも可能です。オブジェクトから要素を削除するにはdeleteを使い、配列内の全てにオブジェクトに共通のdelete処理を実施したいのでmap関数を使います。例えば、text要素を削除したい場合は次のようになります。

itemlist.map((item) => delete item.text))

オブジュクトの更新

配列から特定のオブジェクトを削除するためには、配列操作メソッドの1つであるmap()を使用しますが、まずは追加の場合と同様に更新対象のオブジェクトを作成します。ここでもユーザーからのインプットをもとに作成された更新オブジェクトにidはないも、削除の場合と同様に内部的に更新対象オブジェクトのidは特定可能で、同idを変数idに格納します。

const updateItem = {
rating: 4,
text: "Updated the text of 2nd item",
}

配列に対してmapメソッドを使うと、配列内の各要素に対して共通の処理を施し、同処理を実行後の要素を持つ新たな配列を得ることができます。ここでは、各要素itemに対してif文(三項演算子)を使って処理を実行しています。すなわち、各要素itemのidが更新対象の対象のidと等しい場合(更新対象の場合)は、2項目を返し、itemのidが更新対象のidと等しくない場合(更新対象でない場合)は、各要素itemをそのままの形で返しています。

itemlist.map((item) => (item.id === id ? { ...item, ...updateItem } : item))

2項目は、追加でも使った3つのドット…(スプレッド構文)を使います。追加の例では配列内でスプレッド構文を使用したのに対し、この更新の例ではオブジェクトの内部で2つのスプレッド構文を使用します。

オブジェクトの内部で2つのスプレッド構文を使用すると、2つのオブジェクトが結合して新たなオブジェクトを生成しますが、2つのオブジュクトでプロパティ名(キー)に重複がある場合は、後者の内容にて前者を上書きします。重複がない場合は、前者のプロパティと値がそのまま維持されるので更新に使えるということになります。よって、この事例ではupdateItemを使ってratingとtextが更新されますが、updateItemはidを持ちませんので、itemのidは更新されずにそのままとなります。map()よって以上の処理が全ての要素に実行され、更新された要素を含む新たな配列が得られます。

今日も最後まで読んで頂きありがとうございました。