【JavaScript】オブジェクトの配列を操作するときの基礎チュートリアル

## はじめに
こんにちは。masakichiです。

わたしは、Reactを使ってコーディングする時、よくJSONデータを操作する場面に遭遇してきました。

単純な配列に対する操作であれば、ネット上に情報が溢れています。
しかし、オブジェクト形式の配列の場合、情報が少なく、困ったことが多々ありました。

そこで今回はオブジェクト形式の配列を操作する基本的な内容をまとめておきたいと思います。

## 今回操作するオブジェクトの配列

前提条件として、今回の記事内で操作するオブジェクトの配列は下記を利用することとします。
生徒の情報が入ったオブジェクトを配列にしたものです。

```javascript
let students = [
  {
    name: "ichiro",
    class: "classA",
    major: "mathematics",
    hobby: "baseboll"
  },
  {
    name: "jiro",
    class: "classB",
    major: "science",
    hobby: "baseboll"
  },
  {
    name: "saburo",
    class: "classA",
    major: "science",
    hobby: "soccoer"
  }
];
```

## `Array.unshift` - 配列の先頭にオブジェクトを追加する
配列の先頭に新しいオブジェクトを追加するには`unshift`を使います。

**構文**
```javascript
Array.unshift(新しいオブジェクト) 
```

**例**

```javascript
let student = {
  name: "rokuro",
  class: "classA",
  major: "history",
  hobby: "soccer"
};

students.unshift(student);

console.log(students);

// 出力:
// [
//   {
//     name: "rokuro",
//     class: "classA",
//     major: "history",
//     hobby: "soccer"
//   },
//   {
//     ...
//   },
//   ...
// ]
```

MDN : [Array.prototype.unshift()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/unshift)

## `Array.push` - 配列の最後にオブジェクトを追加する
逆に配列の最後に新しいオブジェクトを追加するには`push`を使います。

**構文**
```javascript
Array.push(新しいオブジェクト) 
```

**例**
```javascript
let student = {
  name: "rokuro",
  class: "classA",
  major: "history",
  hobby: "soccer"
};

students.push(student);

console.log(students);

// 出力:
// [
//   {
//     ...
//   },
//   ...
//   {
//     name: "rokuro",
//     class: "classA",
//     major: "history",
//     hobby: "soccer"
//   }
// ]
```

MDN : [Array.prototype.push()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/push)

## `Array.splice` - 配列の途中にオブジェクトを追加する

`Array.splice`を使うと、配列の途中の位置にオブジェクトを追加することができます。
しかし、本来、spliceメソッドは既存の要素を取り除いたり、置き換えたりなど、配列の内容を変更する関数のため、引数の取り方には注意しましょう。

**構文**
```javascript
Array.splice(start, deleteCount, item)

//start：変更の開始位置のインデックス
//deleteCount：取り除くアイテムの数（省略可）
//item：配列に追加する要素（省略可）
//※deleteCount が 0 または負の数の場合、どの要素も取り除かれない
```

**例**  
新しい生徒を配列の2番目に追加してみます。

```javascript
let student = {
  name: "rokuro",
  class: "classA",
  major: "history",
  hobby: "soccer"
};

students.splice(1, 0, student);

console.log(students);

// 出力:
// [
//   {
//     name: "ichiro",
//     class: "classA",
//     major: "mathematics",
//     hobby: "baseboll"
//   },
//   {
//     name: "rokuro",
//     class: "classA",
//     major: "history",
//     hobby: "soccer"
//   },
//   {
//     ...
//   },
//   ...
// ]
```

MDN : [Array.prototype.splice()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/splice)

## `Array.find` - 配列内のオブジェクトを特定の値で検索する
配列内で特定の値を持つオブジェクトを検索するには`Array.find`を使います。
findメソッドは引数にテスト関数を受け取ります。
テスト関数を満たす配列内の最初の要素を1つ返します。テスト関数を満たす値がない場合は、`undefined`を返します。

**構文**
```javascript
Array.find((element) => { /* ..テスト内容.. */ } )
```

**例**

```javascript
let student = students.find(student => student.name === "jiro");

console.log(student);
// 出力:
// {
//   name: "jiro",
//   class: "classB",
//   major: "science",
//   hobby: "baseboll"
// },

let student = students.find(student => student.name === "taro");

console.log(student);
// 出力:
// undefined
```

MDN : [Array.prototype.find()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/find)

## `Array.findIndex` - 配列内のオブジェクトを特定の値で検索して、そのIndexを返す
配列内で特定の値を持つオブジェクトの位置を取得したい場合は`Array.findIndex`が使えます。
findメソッドと同じように、引数にテスト関数を受け取ります。
テスト関数を満たす配列内の最初の要素のIndexを1つ返します。テスト関数を満たす値がない場合は、`-1`を返します。

**構文**
```javascript
Array.findIndex((element) => { /* ..テスト内容.. */ } )
```

**例**

```javascript
let student = students.findIndex((student) => student.name === "jiro");

console.log(student);
// 出力:
// 1

let student = students.findIndex((student) => student.name === "taro");

console.log(student);
// 出力:
// -1
```

MDN : [Array.prototype.findIndex()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex)

## `Array.filter` - 配列から条件に一致するオブジェクトを複数取得する
`Array.find`関数は条件に一致する最初のオブジェクトだけ返しました。
条件を満たす全てのオブジェクトを取得する場合は、`Array.filter`を使います。

**構文**
```javascript
Array.filter((element) => { /* ..テスト内容.. */ } )
```

**例**
```javascript
let filterStudents = students.filter((student) => student.class === "classA");

console.log(filterStudents);

// 出力:
// [
//   {
//     name: "ichiro",
//     class: "classA",
//     major: "mathematics",
//     hobby: "baseboll"
//   },
//   {
//     name: "saburo",
//     class: "classA",
//     major: "science",
//     hobby: "soccoer"
//   }
// ];
```

MDN : [Array.prototype.filter()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/filter)

## `Array.map` - オブジェクトの配列から新しいオブジェクトの配列を生成する
`map`メソッドを使うと、引数として与えられた関数が配列のすべてのオブジェクトを呼び出し、その結果からなる新しい配列を生成することができます。

**構文**
```javascript
let new_array = arr.map(function callback(currentValue) {
    // 新しい配列の要素を返す
    return newObeject;
})
```

**例**

例として、classの値を全て`classB`に変えてみます。

```javascript
let newStudents = students.map((student) => {
  let newStudent = {
    ...student,
    class: "ClassB"
  };

  return newStudent;
});

console.log(newStudents);
// 出力:
// [
//   {
//     name: "ichiro",
//     class: "classB",
//     major: "mathematics",
//     hobby: "baseboll"
//   },
//   {
//     name: "jiro",
//     class: "classB",
//     major: "science",
//     hobby: "baseboll"
//   },
//   {
//     name: "saburo",
//     class: "classB",
//     major: "science",
//     hobby: "soccoer"
//   }
// ];
```

MDN : [Array.prototype.map()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map)

## `Array.every` - 配列内の全てのオブジェクトが条件を満たすかチェックする

`Array.every`は配列内のすべての要素が指定された関数の条件を満たすかどうかをテストすることができます。

結果は論理値を返します。

**構文**

```javascript
arr.every((element) => { /* ..テスト内容.. */ })
```

**例**
```javascript
let every = students.every((student) => {
  return student.class === "classA" || "classB";
});

console.log(every);
// 出力
// true

let every = students.every((student) => {
  return student.class === "classA";
});

console.log(every);
// 出力
// false
```

MDN : [Array.prototype.every()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/every)

## `Array.some` - 配列内の少なくとも1つのオブジェクトが条件を満たすかチェックする

`Array.every`は配列内のすべての要素に対して、条件を満たすかチェックしました。

`Array.some`は少なくとも1つのオブジェクトが条件を満たすかチェックすることができます。

結果は同じく論理値を返します。

**構文**

```javascript
arr.some((element) => { /* ..テスト内容.. */ })
```

**例**
```javascript
let some = students.some((student) => {
  return student.class === "classA";
});

console.log(some);
// 出力
// true
```

MDN : [Array.prototype.some()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/some)

## おわりに
ReactではJSONデータを扱うことが多々あるので、オブジェクト形式の配列の操作方法を知っておくことはとても大事だと思っています。
プリミティブ型の配列の操作方法と共通することもありますが、オブジェクト配列の場合はコールバック関数を扱うことが多いので、基本的なメソッドや使い方などは慣れておいた方がいいなと感じました。


## 参考文献
- [JavaScript Array of Objects Tutorial – How to Create, Update, and Loop Through Objects Using JS Array Methods](https://www.freecodecamp.org/news/javascript-array-of-objects-tutorial-how-to-create-update-and-loop-through-objects-using-js-array-methods/)
- [MDN Web Docs - Array](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array)