MENU

【Javascript】配列を操作するメソッドまとめ

2021 6/02
【Javascript】配列を操作するメソッドまとめ

おつかれさまです!
最近はHuluでドラマに明け暮れている日々です。りっくんです。

今回はJavascriptで配列を扱う上で重要なメソッドに関して、いくつか紹介したいと思います。
個人的にも今まで度々使ってきたものもありましたが、改めて理解を深めるためにも備忘録として記していきたいと思います。

目次

forEach

それではforEachから。

基本構文:

 // value:配列のデータ値
 // index:配列のインデックス
 // array:現在処理している配列

 arr.forEach( function( value, index, array ) {
  // 繰り返し処理
 });

※引数のindexとarray(現在使用している配列)は省略可能。

戻り値:undefined

forEach自身の役割を端的に言えば配列の各要素に対してループを回す、それだけ。

ただループを回して決められた処理をこなすだけっていう感じです。

forEachそのものは使用用途を絞ったものではないので、この後に紹介するメソッドと比べると基本的にはなんでもできるものになります。

↑一見万能そうに聞こえますが、実際に中で何をしているかということを読み解くには実装の詳細を追う必要があるので、コードを理解する負荷がかかります。要するにメソッドだけ見ても実装内容が読めない。
(と言いつつ、私自身他のメソッドとまだ仲良くできていない点も多いので、いつもお世話になっていますが。、)

※forEachメソッドによるループは基本的に途中で中断することができません。

使用例:配列の中にあるデータを取り出してリストを作る。

See the Pen QWpOGyv by rik9228 (@rik9228) on CodePen.

find

続いてfind。

基本構文:

let newArray = arr.find( function( value, index, array  ){
 // 条件処理
 return hogehoge; // 戻り値を返す
 });

※引数のindexとarray(現在使用している配列)は省略可能。

戻り値:配列の中で任意の条件に合致した最初の要素(単一要素)
▶︎ 見つからなかった場合はundefinedを返す。

findでは対象の配列の中から条件に合致する要素を取り出して、それだけを返すといったイメージです。(条件にマッチする要素が見つかるまでループします)

forEachと違う点の一つとして、戻り値を返すかどうかです。(forEachでは厳密にはundedfinedが返ってきます)

findは配列の中から条件に合う単一のものだけが欲しいという場面で非常に有効です。

使用例:配列の中から”佐藤”を取り出す。

const arr = ['佐藤','田中','武田','岩田'];

let newArray = arr.find((elem)=>{
  if(elem === '佐藤'){
    return elem;
  }
});

console.log('result:', newArray); // result:  '佐藤';

コンソールの結果"result:", '佐藤';

filter

基本構文:

let newArray = arr.filter( function( value, index, array  ){
 // 条件処理
 return hogehoge; // 戻り値を返す
 });

※引数のindexとarray(現在使用している配列)は省略可能。

戻り値:配列の中で条件に合致した要素だけで構成される新たな配列
▶︎ 条件に合致しなかった要素(false)は取り除かれる。

一見findと似ていますが、単一の要素を返すか配列を返すかで大きく違ってきます。

仮に配列の中から何一つ条件が合致しなかった場合は空の配列が返ります

Todoアプリとかで絞り込みをする時なんかはこのメソッドが有効です。

使用例:配列の中から”佐藤”以外のものを取り出す。

const arr = ['佐藤','田中','武田','岩田'];

let newArray = arr.filter((elem)=>{
  if(elem !== '佐藤'){ // 佐藤以外の要素を対象としている(truthy)ので、'田中','武田','岩田'が条件をパスする。
    return elem;
  }
});

console.log('result:', newArray); 
// result:  ["田中","武田","岩田"];

コンソールの結果:"result:", ["田中","武田","岩田"];

map

基本構文:

let newArray = arr.map( function( value, index, array  ){
 // 任意の処理
 return hogehoge; // 戻り値を返す
 });

※引数のindexとarray(現在使用している配列)は省略可能。

戻り値:配列の各要素に任意の処理を行い、その結果からなる新しい配列

find、filterでは条件の絞り込みということが主な役割でしたが、ここでは主に配列の各要素に対して加工や整形を行うことが主な用途になるでしょうか。

filterでもそうですが、あくまで返すのは新しい配列なので、元の配列データには破壊的な干渉が及びません。

使用例:配列の各様要素の全てに”さん”をつける。

const arr = ['佐藤','田中','武田','岩田'];

let newArray = arr.map((elem)=>{
  return elem + 'さん';
});

console.log('result:', newArray); 
// "result:", ["佐藤さん", "田中さん", "武田さん", "岩田さん"]

コンソールの結果:"result:", ["佐藤さん","田中さん","武田さん","岩田さん"];

some,every

some

基本構文:

let newArray = arr.some( function( value, index, array  ){
 return //任意の条件
 });

※引数のindexとarray(現在使用している配列)は省略可能。

戻り値:配列の各要素に任意の処理を行い、条件に合致した要素がひとつでもあった場合(truthy)はtrue
▶︎ そうでない場合はfalse

使用例:年齢が40歳以上の人が一人でもいるかどうかをチェックする

const arr = [{
'name':'佐藤',
'gender':'男',
'age':25,
},
{
'name':'田中',
'gender':'女',
'age':32,
},
{
'name':'武田',
'gender':'男',
'age':38,
},
{
'name':'岩田',
'gender':'女',
'age':29,
},

];

let newArray = arr.some((elem,index)=>{
  return elem.age > 40
});

console.log('result:', newArray); 
// "result:", false;

コンソールの結果:"result:", false;

every

基本構文:

let newArray = arr.every( function( value, index, array  ){
 return //任意の条件
 });

※引数のindexとarray(現在使用している配列)は省略可能。

戻り値:配列の各要素に任意の処理を行い、条件に合致した要素がひとつでもあった場合(truthy)はtrue
▶︎ そうでない場合はfalse

使用例:全員、年齢が20歳以上の人であるかどうかをチェック

const arr = [{
'name':'佐藤',
'gender':'男',
'age':25,
},
{
'name':'田中',
'gender':'女',
'age':32,
},
{
'name':'武田',
'gender':'男',
'age':38,
},
{
'name':'岩田',
'gender':'女',
'age':29,
},

];

let newArray = arr.every((elem,index)=>{
  return elem.age > 20
});

console.log('result:', newArray); 
// "result:", true;

コンソールの結果:"result:", true;

some、everyと続きましたが今までとのメソッドとの違いは返り値の内容になります。

今までのメソッドでは条件に合う要素や新しい配列など、要素を返していましたが、someとeveryはBoolean(論理値)を返すものになります。

主な使用用途としてはフォームでの必須条件とかバリデーションの部分かなーと思います。

(まだあまり使ったことがないので、おそらくはって感じです。)

reduce

reduceですが、これまでのメソッドとは少し仕組みが異なるので最後に持ってきました。

これは何をするものかと言うと、配列の各要素を使って1つの値を返すといったものになります。

基本構文:

let newArray = arr.reduce( function( accumulator, value, index, array  ){
 // 任意の処理
 return hogehoge; // 戻り値を返す
 },initialValue(初期値));

※引数のindexとarray(現在使用している配列),initialValue(初期値)は省略可能。

戻り値:コールバック関数の中で配列の各要素を用いて、その結果からなる1つの値

引数:accumulator, value, index, array の4つの引数

実際にコードを見ながら追っていきましょう。

サンプル:

const arr = [1,2,3,4,5];

let newArray = arr.reduce((acc,current)=>{
 return acc  +  current ;
},0);

console.log('result:', newArray);

コンソールの結果:"result:", 15;

具体的な動き:

callback の呼び出しaccumulatorcurrentValuecurrentIndexarray
初回0(初期値)10[1,2,3,4,5]1
2回目1(初回の呼び出しで返された値)21[1,2,3,4,5]3
3回目3(2回目の呼び出しで返された値)32[1,2,3,4,5]6
4回目6(3回目の呼び出しで返された値)43[1,2,3,4,5]10
5回目(最終)10(4回目の呼び出しで返された値)54[1,2,3,4,5]15
reduceの動き

表にしてみると少しは分かりやすいかも?

[1,2,3,4,5]の配列を使って上でreduceを回すことによって、最終的に15の値が返されます。

accumulatorはreduceメソッドで扱われる、蓄積値のようなイメージです。

こちらでは、コールバックの処理が走るごとに acc + current の処理が走ります。

一度コールバック処理を終えるとacc(accumulator)に acc + current で返される値が蓄積され、次回のコールバック処理に移ります。

初回に上の表でaccumulatarが0となっているのは、初期値に0を指定しているからです。↓↓↓

let newArray = arr.reduce((acc,current,index)=>{
 console.log('index:', index);
 return acc  +  current ;
},0); // 初期値

//
'index:',0
'index:',1
'index:',2
'index:',3
'index:',4
"result:", 15;

ちなみに初期値は省略することができます。省略するとcurrentIndexが1の状態からループ処理が走る仕組みになっています。

※初期値を省略した場合:

const arr = [1,2,3,4,5];

let newArray = arr.reduce((acc,current,index)=>{
 console.log('index:', index);
 return acc  +  current ;
}); //ここをなくす

console.log('result:', newArray_02);

// 
'index:',1
'index:',2
'index:',3
'index:',4
"result:", 15;

// コンソールの結果:
‘index:’,1
‘index:’,2
‘index:’,3
‘index:’,4
“result:”, 15;

‘index:’, 0がスキップされていますね。

ところがreduceメソッドの第二引数を省略することで以下のような弊害が発生します。

  • 空配列に対して初期値を指定しない場合にreduce()メソッドを呼ぶとTypeErrorが発生する
  • 要素が一つしかない配列に対して初期値を指定しないreduce()メソッドを呼び出すとコールバック関数が実行されない。

以上の理由から、reduce()メソッドの基本的には第二引数は省略しない方がよいとされています。

サンプル2:

const arr = ['佐藤','田中','武田','岩田'];

let newArray = arr.reduce((acc,current,index,arr)=>{
if(index === arr.length - 1){ 
 return acc  +  current + 'さん'; //最後のコールバックループ時はここに分岐
}
 return acc  +  current + 'さん、';
 
},'名簿リスト:');

console.log('result:', newArray);
// "result:", "名簿リスト:佐藤さん、田中さん、武田さん、岩田さん"

コンソールの結果:"result:", "名簿リスト:佐藤さん、田中さん、武田さん、岩田さん"

少しとっつきにくいですが、使いこなせばfilter や mapメソッドを同時に行うことができたりするので、とても万能なメソッドだと言えます。自分ももうちょっと仲良くなります。、!

まとめ

いかがだったでしょうか。

今回紹介したものは配列を扱う上で、頻繁に登場するかつ重要な役割を担っています。

今回記事を執筆してみて個人的にも改めて勉強になったので、とても良い機会になりました。

まだまだforEachに依存しているところがあるので、もう少し用途に沿って限定的に適切なメソッドを扱えるようにもっと勉強したいと思います…!

それではまた次回お会いしましょう〜!✋


もりけん塾で学習中!(JS課題難しい

もりた先生のブログ: kenjimorita.jp (武骨日記)
もりた先生のアカウント: twitter.com/terrace_tech

この記事を書いた人

コメント

コメントする

CAPTCHA


目次
閉じる