0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【JavaScript】追加学習分〜③「配列を操作するメソッド」

Last updated at Posted at 2021-11-23

##1. はじめに
これまで記事にしてきたJavaScriptの学習に関して、抜けがあった分を記載する。
今回は「配列を操作するメソッド」に関して記述していきたい。
前回学んだ「関数」をたくさん使うので、配列操作のメソッドを学ぶとともに関数を復習する意味で進めていく。
##2. forEachメソッド
###forEachメソッドとは?
JavaScriptにおいて、配列に特化したループ処理である。
コールバック関数※に実行したい内容を記述することで、
配列の要素ひとつひとつに対して繰り返し処理を実行する。

ある関数を呼び出す時に、引数に指定する別の関数のこと。


過去に繰り返し処理の記事を書いているので、復習の意味も込めてリンクを掲載。
繰り返し処理の記事一覧
for
while
do while

###forEachでできること forEachでは、配列の各要素に対する繰り返し処理を一括で指示することができる。 ####forでのデメリット :::note 配列内のデータを順に出力するには ループの終了条件カウンターなどの設定 が必要となり、少し複雑なコードになりがちになる。 ::: ####forEachにすることのメリット :::note コールバック関数に実行したい処理内容を記述するだけで済むので、 コードをシンプルにまとめることができ、ミスの軽減や管理がしやすくなるといったメリットがある。 :::
###forEachの基本と使い方 forEachの書式や基本的な使い方は以下の通り。 ####書式 ```index.js 配列名.forEach( コールバック関数(要素の値) ) 配列名.forEach( コールバック関数(要素の値, 要素のインデックス) ) 配列名.forEach( コールバック関数(要素の値, 要素のインデックス, 配列) ) ``` #####書式の概要 :::note forEachメソッドは、 配列に含まれる要素を先頭から順に取り出しコールバック関数を呼び出す。 ::: :::note コールバック関数は、 現在取り出されている要素の値要素のインデックス、 そして配列そのものを引数にして呼び出される。 ::: :::note 引数の要素のインデックスおよび配列は必要なければ省略可能。 ::: ####基本的な使い方 今回は3パターン用意した。 (他にも使い方の例はあるかもだけど、今回はとりあえず3つ) #####forEachメソッドの引数に記述したコールバック関数を呼び出す
サンプル
index.js
let fruit = ['Apple', 'Melon', 'Orange'];

fruit.forEach(function (element) {
  console.log(element);
});

【実行結果】

Apple
Melon
Orange

配列に含まれる要素の値である 'Apple', 'Melon', 'Orange' を順に取り出し
forEachメソッドの引数に記述したコールバック関数を呼び出している。


#####アロー関数を使った記述
サンプル
index.js
let fruit = ['Apple', 'Melon', 'Orange'];

fruit.forEach((element) => console.log(element));

【実行結果】

Apple
Melon
Orange

実行結果は1つ前の例題と同様となる。
こちらの方が簡潔に書けるのがメリット。


#####要素のインデックスや配列をコールバック関数の引数として受け取って処理する場合
サンプル
index.js
let fruit = ['Apple', 'Melon', 'Orange'];

fruit.forEach(function (element, index, array) {
  console.log('Index:' + index);
  console.log('Element:' + element);
  console.log('Array:' + array);
});

【実行結果】

Index:0
Element:Apple
Array:Apple,Melon,Orange
Index:1
Element:Melon
Array:Apple,Melon,Orange
Index:2
Element:Orange
Array:Apple,Melon,Orange
下記図解にて解説。
図を使って解説
![スクリーンショット 2021-11-21 13.20.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/662822/4f15066c-feef-86ae-79e0-8146d87ca958.png)
forEachの()内を入れ換えると以下の出力結果になる。
サンプル:()内入れ替え
index.js
let fruit = ['Apple', 'Melon', 'Orange'];

fruit.forEach(function (index, element, array) {
  console.log('Index:' + index);
  console.log('Element:' + element);
  console.log('Array:' + array);
});

【出力結果】

Index:Apple
index.js:5 Element:0
index.js:6 Array:Apple,Melon,Orange
index.js:4 Index:Melon
index.js:5 Element:1
index.js:6 Array:Apple,Melon,Orange
index.js:4 Index:Orange
index.js:5 Element:2
index.js:6 Array:Apple,Melon,Orange
出力結果がめちゃくちゃなことになっているが、それには理由がある。 [forEachの書式](https://qiita.com/Stack_up_Rising/items/1744ae3490747f0eb028#%E6%9B%B8%E5%BC%8F )で書いたが、
index.js
配列名.forEach( コールバック関数(要素の値, 要素のインデックス, 配列) )

なので、正しく入力しないと出力結果が狙ったものにならないので注意すること。


###配列の繰り返し処理におけるforEachメソッドとforの違い 配列の要素を順に取り出して処理する方法として forEachメソッドを使う以外にforやfor...ofを使うことも出来る。 (for...ofは[こちら](https://qiita.com/a05kk/items/d6f49ca5bd15f045ea6c#forof)で解説されているので参考までに)
####forEach、for、for...ofの違い 下記はforEach、for、for...ofを使ってコードを書いてみた。
forEach
index.js
let alpha = ['A', 'B', 'C'];

alpha.forEach(function (element) {
  console.log(element);
});

【実行結果】

A
B
C
for
index.js
let alpha = ['A', 'B', 'C'];

for (let i = 0; i < alpha.length; i++) {
  console.log(alpha[i]);
}

【実行結果】

A
B
C
for...of
index.js
let alpha = ['A', 'B', 'C'];

for (let element of alpha) {
  console.log(element);
}

【実行結果】

A
B
C
いずれの形式でも同じ結果となる。 ただし、

配列の要素のインデックスが連続しておらず、
途中に存在しない要素がある場合には異なった結果となる

実際どのようなものか?
下記は変数alphaに対し配列['A', 'B', , , 'C'];を格納した上で3つの文法を書いてみた。

forEach
index.js
let alpha = ['A', 'B', , , 'C'];

alpha.forEach(function (element) {
  console.log(element);
});

【実行結果】

A
B
C
for
index.js
let alpha = ['A', 'B', , , 'C'];

for (let i = 0; i < alpha.length; i++) {
  console.log(alpha[i]);
}

【実行結果】

A
B
undefined
undefined
C
for...of
index.js
let alpha = ['A', 'B', , , 'C'];

for (let element of alpha) {
  console.log(element);
}

【実行結果】

A
B
undefined
undefined
C
実行結果を見てわかるように、 forEachだけ出力された結果は3つで、 forとfor...ofだけundefindedを含む5つ という結果となった。 なぜかと言うと、

forEachメソッドは存在しない要素に対しては何も行われないから。

forとfor...ofでは存在しない要素に対しても同じように処理を行うから


####forEach、for、for...ofの違い〜breakを使用した場合〜 :::note forEachメソッドを使用している場合は、 breakが使用できないため繰り返し処理を途中で止めることは出来ない。 ::: :::note orまたは for...ofの場合は、 breakを使用することで繰り返し処理を途中で終了させることが出来る。 ::: そもそも[過去に記事にしたfor](https://qiita.com/Stack_up_Rising/items/b70ef528d9c9c608fc8a)や[while](https://qiita.com/Stack_up_Rising/items/a4f72612e6c8ae5b0e89)でbreakの箇所を書いていなかったので、改めて記事にしてみたいと思う。 #####breakを使ったforやwhile breakが実行されると、 breakが記述されている最も内側の繰り返し処理が終了し次の処理へ移る。 書式は、終了してほしい箇所(次に移りたい箇所)で`break;`と入力するだけ。 実際にforとwhileでbreakを含めてコードを作成すると以下の図ようになる。
for図解
![for.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/662822/8a44a032-b6a2-dc72-acf6-2387eb520d02.png)
whileの図解
![while.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/662822/949ead2c-8b17-769d-a406-bf570dae5480.png)
forとwhileとでは繰り返し処理の性質は異なるが、 breakの意味と役割は同様のものとなる。 #####bleakを織り交ぜた例題〜for 実際に例題を挙げて解説していく。 例題の内容は以下の通り。

変数numの値を順に2倍しながら数値をコンソールに出力

繰り返す回数は10回

for+break
index.js
let num = 1;

for (let i = 0; i < 10; i++) {
  console.log(num);
  num *= 2;
  if (num > 10) {
    console.log('10を超えたので繰り返し処理を抜けます');
    break;
  }
}
console.log('end');

【出力結果】

1
2
4
8
10を超えたので繰り返し処理を抜けます
end

変数numの値が10を超えた場合は、
その時点で繰り返し処理を終了させてforの次の処理へ移っている

先ほどのコードでbreakが記述されている最も内側のブロックはif文だが、
if文はbreakの対象ではないためその外側のforのブロックを抜けている

#####bleakを織り交ぜた例題〜while

whileの条件式がtrueとなっており、
ランダムの数値が6だった場合にbreakが実行されるようにする。

while+break
index.js
while (true) {
  let dice = Math.floor(Math.random() * 6) + 1;
  console.log(dice);
  if (dice == 6) {
    break;
  }
}
console.log('end');

Math.floor:対象の値の小数点以下を切り捨てた値を取得するメソッド。
Math.random():乱数を生成し返してあげるメソッド。-1は最小値で、6は最大値の意味。
【出力結果】

2
6
end

乱数で出た数値が6だった場合にはbreakが実行されて
whileの次へ処理が移るようになる。

※出力結果はランダムなので結果もランダム
##3. findメソッド
###findメソッドとは?
:::note
コールバック関数の処理部分に
記述した条件式に合う1つの要素を配列の中から取り出すメソッド

のこと。
:::
簡潔に言うと、

配列の中から上から順番に検索して、最初に条件に合致するものを返す

ということ。
実際に例題を書いて説明していく。
###例題(1)
####内容
:::note warn
配列内にランダムな整数を格納し、その中から3より大きい整数をコンソールへ出力する。
:::
実際に書いていくと以下のようになる。

index.js
index.js
const numbers = [1, 3, 5, 7, 9];
const foundNumber = numbers.find((number) => {
  return number > 3;
});
console.log(foundNumber);

【出力結果】

5
#####解説 図を使って解説していく。 ![スクリーンショット 2021-11-23 19.19.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/662822/4ba9aae0-af4d-f0bd-ac10-48dcf7b9b05e.png) 図で記載の通り、 findメソッドは最初に当てはまる最初の要素を返す という性質があるので、返される数値は5ということになる。 他にも例題を書いてみた。
###例題(2) ####内容 今度は内容を複雑化してみた。

配列内にid・name属性を持たせた複数の配列に対し、
特定のidの番号をfindメソッドを使って返す。

実際に書いていくと以下のようになる。

index.js
index.js
const persons = [
  { id: 1, name: "鈴木" },
  { id: 2, name: "田中" },
  { id: 3, name: "茂木" },
  { id: 4, name: "岡島" },
  { id: 5, name: "小原" }
];
const foundPerson = persons.find((person) => {
  return person.id === 4;
});
console.log(foundPerson);

【出力結果】

{id: 4, name: '岡島'}
#####解説 こちらも図で解説していく。 ![スクリーンショット 2021-11-23 20.27.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/662822/693dba24-4b9c-1a35-1aea-5bd57a4685d5.png) 今回の例は、オブジェクトのプロパティを条件としている。 よって、その場合はプロパティが保持しているオブジェクトそのものが取り出される

なので、定数persons内の中に格納されているid〜の箇所すべてがコンソールへ出力される。
##4. filterメソッド
###filterメソッドとは?
:::note
条件に合う要素のみを取り出して新しい配列を作成するメソッドのこと。
:::
実際に例題を書いて説明していく。
###例題(1)
####内容
:::note warn
配列numbersの要素が1つずつ引数numberに代入される。
:::
:::note warn
その後filterメソッド内で「3より大きい数字」かどうかを判定し、
条件に合う要素が定数filteredNumbersに配列として代入される。
:::

index.js
index.js
const numbers = [1, 3, 5, 7, 9];
const filteredNumbers = numbers.filter((number) => {
  return number > 3;
});
console.log(filteredNumbers);

【出力結果】

[5, 7, 9]
#####解説 コードの読み解き方としてはfindメソッドと同様なので割愛する。 findメソッドと違い、該当する値すべてが出力されることがわかる。
###例題(2) :::note warn 配列内にname(名前)・age(年齢)を持たせた複数の配列に対し、 age(年齢)をfindメソッドを使って返す。 :::
index.js
index.js
const animals = [
  { name: "cat", age: 7 },
  { name: "dog", age: 9 },
  { name: "elephant", age: 14 },
  { name: "mouse", age: 13 },
  { name: "lion", age: 16 }
];
const filteredAnimals = animals.filter((animal) => {
  return animal.age > 10;
});
console.log(filteredAnimals);

【出力結果】(デベロッパーツールよりキャプチャー)
スクリーンショット 2021-11-23 21.23.20.png

#####解説 [findメソッドで解説](https://qiita.com/Stack_up_Rising/items/1744ae3490747f0eb028#%E8%A7%A3%E8%AA%AC-1 )した内容と被ってしまうが、 プロパティが保持しているオブジェクトそのものが取り出される。 ##5. mapメソッド :::note 配列内のすべての要素に処理を行い、その戻り値から新たな配列を作成するメソッドのこと。 ::: 実際に例題を書いて説明していく。 ###例題(1) ####内容 :::note warn 配列numbersのすべての要素を3倍した要素を持つ、新たな配列を作成する。 :::
index.js
index.js
const numbers = [1, 2, 3];
const tripleNumbers = numbers.map((number) => {
  return number * 3;
});
console.log(tripleNumbers);

【出力結果】

[3, 6, 9]
#####解説 mapメソッドを使い、引数numberに代入された値を3倍にしてreturnで返している。
###例題(2) 今度は文字列を使ったmapメソッドを見ていく。

ファーストネームとラストネームをmapメソッドでつなげていく。

index.js
index.js
const names = [
  { firstName: 'Andrew', lastName: 'Jones' },
  { firstName: 'Casey', lastName: 'McGehee' },
];
const fullNames = names.map((name) => {
  return name.firstName + name.lastName;
});
console.log(fullNames);

【出力結果】

['AndrewJones', 'CaseyMcGehee']
#####解説 nameオブジェクトを、それぞれ配列内で記述したプロパティに紐付ける。 ↓ それをreturnで返してやるとプロパティ同士がつながって出力される。 ##6. pushメソッド :::note 配列の最後に新しい要素を追加するメソッドのこと。 :::

実際に例題を書いて説明していく。
###例題
####内容
:::note warn
1〜3の配列を出力した後に、新たに4を配列の最後に出力する。
:::

index.js
index.js
const numbers = [1, 2, 3];
console.log(numbers);

numbers.push(4);
console.log(numbers);

【出力結果】

[1, 2, 3]
[1, 2, 3, 4]
#####解説 簡素なコードになっているが、これで新たな配列を出力することが出来る。 (文字列の場合も同様なので割愛する) ##7. おわりに まだまだ学習漏れな部分があると思うので、見つけ次第どんどん追加していきたい。 また、propsメソッドを書こうかどうか悩んだが、これはReactやNext.jsといった ライブラリやフレームワークで使われるものなので今回は書かなかった。 (学習にはまだ早すぎる…)
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?