トップ画像イメージ

未だにfor文結構使っているコード見ることが多い・・・

筆者は現在の仕事で、Rails + jquery を使った開発を行なっています。

プライベートではvue.jsの学習をしているのですが、その中でES6の書き方を改めて学習しましたので、便利と感じた部分についてまとめておきたいと思います。

筆者の職場含め、配列のループ処理といえば、for文で回すだけ・・・って結構思っている方が多いと思います。ES6の書き方でいかに、効率的な書き方ができるか、自分のためにまとめておこうと思います。

constletやアロー関数については、別途記事にするつもりですので、変数の宣言にはvarを利用し、アロー関数を利用しない書き方をしています。

forEach

Rubyの#eachよろしく、arrary#forEachという風に使えるので、 一目で何の配列のループ処理をしているか分かりやすい。

とはいえ、forEachはのちに説明するmapfilterなどのメソッドが使えない時に利用するのが良いらしい。(汎用的に使えるけど、他に簡潔に書けるメソッドがあれば、そちらを使う。)

例えば、配列の特定要素を抜き出したいならfilter、配列に対して何か処理をした後に、新たな配列を戻り値として欲しいなら mapを使う。


var nums =['1','2','3']
//for文の場合
for (var i = 0; i < nums.length; i++){
		console.log(nums[i]);
}
//forEachの場合
nums.forEach(function(num){
		console.log(num);
});
//ループ処理したい配列について、処理したいコールバック関数を引き渡す感じ

全般に言えることだけど、引き渡すコールバック関数は無名関数だけでなく、名前のついた関数も引き渡せる

//numbersの合計をsumに格納する
var numbers = [1,2,3];
var sum = 0;

function numbers_sum(num){
  sum += num;
}

//配列の一つ一つの数字を合計に足す
numbers.forEach( numbers_sum )
//合計を表示する
console.log(sum);

配列.foreachという書き方になるので、従来のfor文より何の配列に対して処理を行っているのか、分かりやすい気がする。

map

//配列の数値を2倍した数値を新たな配列に格納する
var nums =[1,2,3];
var double_nums = [];
//for文の場合
for (var i = 0; i < nums.length; i++){
		double_nums.push(nums[i] * 2)
}

//mapの場合
var double_nums = nums.map(function(num){
  return num * 2;
})

Rubyのmapメソッドよろしく、新しい配列で返してくれるので、こちらの方が圧倒的に分かりやすいですね。

pluckメソッドもmapメソッドで簡単に作れますね。

function pluck(array, property) {
  return array.map(function(item){
    return item[property];
  });
}

var members = [{ name: '飯塚',role:'ツッコミ' }, { name: '豊本',role:'小ボケ' }, { name:'角田',role:'大ボケ' }];

console.log(pluck(members,'name'));

filter

配列に対して、条件に合致するものを返してくれる。

var members = [
  { name: '飯塚',role:'ツッコミ' }, 
  { name: '豊本',role:'小ボケ' }, 
  { name:'角田',role:'大ボケ' }
];

members.filter(function(member){
	return member.role !== 'ツッコミ';
})
=>[{"name":"豊本","role":"小ボケ"},{"name":"角田","role":"大ボケ"}]

すっごい便利。 for文で書く場合より、簡潔にどんな条件の要素を抜き出しているか分かりやすい。

例えば、filterの逆で、特定の条件に合致しない条件の要素だけ抜き出した配列を抜き出したい場合は次のように利用できる。

var numbers = [1,2,3];

function reject(array, conditionFunction) {
   return array.filter(function(arr){
   		return !conditionFunction(arr);
   });
}
reject(numbers,function(num){return num > 1});

find

これも、Rubyのfindと同じような使い方が出来る。

配列や、連想配列の中から、特定の条件に合致する最初の要素を抽出する。

var members = [
  { name: '飯塚',role:'ツッコミ',megane: false }, 
  { name: '豊本',role:'小ボケ',megane:true }, 
  { name:'角田',role:'大ボケ',megane:true }
];

members.find(function(member){
  return member.megane === true;
});

=>{"name":"豊本","role":"小ボケ","megane":true}

要素が見つかった時点でループが止まるので、余計な処理を省くことができる。

every

個人的には、これとsomeが結構衝撃だったです。

everyは配列や連想配列において、全ての要素が特定の条件を満たす場合にはTrueを返す。

つまり、これを使えばfor文で数行必要だった処理をすごく短く書くことができます。

//membersのmeganeキーの値が、全員trueかどうか判定

var members = [
  { name: '飯塚',role:'ツッコミ',megane: false }, 
  { name: '豊本',role:'小ボケ',megane:true }, 
  { name:'角田',role:'大ボケ',megane:true }
];

return members.every(function(member){
  return member.megane
});
=>false

some

上のeveryと合わせて、かなり便利。

こちらはが配列や連想配列に対して、要素の中に一つでも特定の条件を満たす要素があれば、Trueを返します

everyが論理積、someが論理和という感じでしょうか。

//membersのmeganeキーの値が、trueのメンバーがいるか

var members = [
  { name: '飯塚',role:'ツッコミ',megane: false }, 
  { name: '豊本',role:'小ボケ',megane:true }, 
  { name:'角田',role:'大ボケ',megane:true }
];

return = members.some(function(member){
  return member.megane
});

=>true

これ本当に便利。現場でfor文で、flg返却用の変数を用意して〜 とかやっているコードを全てこれに置き換えてやりたい・・・まじで。

reduce

Rubyのinjectreduceと同じようなことが出来る。

第一引数にコールバック関数を渡して、第2引数に初期値を渡す。 第一期引数で渡した関数の結果を、1つの値にして返却する。

・・・我ながら説明が下手。

こちらのサイト等をご参照ください。

初心者でも分かるreduce()の使い方とサンプル例まとめ

//例えば配列の数値の合計値を算出するsum関数の実装
var numbers = [1,2,3,4,5];

function sum(array){
  return array.reduce(function(prev_sum,number){
  	return prev_sum += number;
  },0)
}

sum(numbers);

splice

配列への要素の挿入、置き換えが出来る。 置き換えたい要素番号(インデックス)が分かっておけば、置き換えも出来るので、すっごく便利。

ただし、置き換えの場合は当然、元の配列を破壊的に変更するので注意。

splice(抽出開始位置, 取り出す要素数, 削除箇所に挿入する要素, …)という風に利用する。

第2引数に1を指定すれば、その要素だけ置換してくれ、0だと単純に要素を挿入してくれる。

var members = [
  { name: '飯塚',role:'ツッコミ',megane: false }, 
  { name: '豊本',role:'小ボケ',megane:true }, 
  { name:'角田',role:'大ボケ',megane:true }
];
//nameが豊本の要素の要素番号を取得
var findedIndex = members.findIndex(function(member){
	return member.name === '豊本'
});
//豊本の要素をimanauに変更
members.splice(findedIndex,1,{name:'imanau'})
console.log(members)
=>[{"name":"飯塚","role":"ツッコミ","megane":false},{"name":"imanau"},{"name":"角田","role":"大ボケ","megane":true}]

まとめ

  • 業務でよく使っているのは、map、every、some、findあたり
  • また別の機会に、アロー関数やlet、constなどについてまとめたいと思います