Underscore.jsの入り口

第2回 Underscore.jsのコレクションと配列とオブジェクトの機能

この記事を読むのに必要な時間:およそ 7 分

Underscore.jsのコレクションと配列とオブジェクトの機能をご紹介します。

コレクションの機能

Underscore.jsのコレクションの機能をご紹介します。コレクションの機能は配列やオブジェクト,⁠配列のようなオブジェクト」で使えます。

配列のようなオブジェクト

「配列のようなオブジェクト」は配列のように0と正の整数の値をプロパティ名をして持っているオブジェクトです。この「配列のようなオブジェクト」は配列の持つ便利メソッド(join,sliceなど)を直接呼び出せませんが,通常の配列を同じように扱えます。

Argumentsオブジェクト,NodeList オブジェクト(getElementsByTagNameの戻り値)などが「配列のようなオブジェクト」になります。

ここでは,コレクションの主な機能を紹介します。その他の機能につきましては表1に簡単な説明を書きましたので,参考にしていただければと思います。

表1 コレクションの機能

メソッド名説明Alias
_.each(list, iterator, [context]) listの各要素に対してiteratorを実行します。iteratorの引数は(element, index, list)になります。ネイティブの機能でforEach()が使える環境ではそちらを使います。forEach
_.map(list, iterator, [context])listの各要素に対してiteratorを実行した新しい配列を返します。iteratorの引数は(element, index, list)になります。ネイティブの機能でmap()が使える環境ではそちらを使います。collect
_.reduce(list, iterator, memo, [context]) listの各要素に対してiteratorを実行し累積結果を返します。iteratorの戻り値は累積結果であり,次の要素に対してiteratorの呼び出しで引数として渡されます。iteratorの引数は(memo, value)になります。ネイティブの機能でreduce()が使える環境ではそちらを使います。inject, foldl
_.reduceRight(list, iterator, memo, [context])_.reduce()と同等の処理をlistの最後から実行します。ネイティブの機能でreduceRight()が使える環境ではそちらを使います。foldr
_.find(list, iterator, [context]) listの各要素に対してiteratorを実行し,戻り値が最初に真になる値を返します。detect
_.filter(list, iterator, [context])listの各要素に対してiteratorを実行し,戻り値が真になる値を抜き出した配列を返します。ネイティブの機能でfilter()が使える環境ではそちらを使います。
_.where(list, properties) listの各要素に対してiteratorを実行し,properties(オブジェクトのkeyとvalue)と合致するものを抜き出した配列を返します。
_.findWhere(list, properties) listの各要素に対してiteratorを実行し,properties(オブジェクトのkeyとvalue)と最初に合致するものを返します。
_.reject(list, iterator, [context]) listの各要素に対してiteratorを実行し,戻り値が偽になる値を抜き出した配列を返します。
_.every(list, [iterator], [context]) listの各要素に対してiteratorを実行し,戻り値が全て真なら真を,一つでも偽なら偽を返します。ネイティブの機能でevery()が使える環境ではそちらを使います。all
_.some(list, [iterator], [context]) listの各要素に対してiteratorを実行し,戻り値が一つでも真なら真を,全て偽なら偽を返します。ネイティブの機能でsome()が使える環境ではそちらを使います。any
_.contains(list, value) listにvalueが含まれていれば真を返します。include
_.invoke(list, methodName, [*arguments]) listの各要素に対してmethodNameというメソッドを実行した新しい配列を返します。追加されたargumentsはメソッドの実行時に渡されます。
_.pluck(list, propertyName) listに各要素にpropertyにpropertyNameで指定した値が含まれた新しい配列を返します。_.map()のよく用いられる使われ方です。
_.max(list, [iterator], [context]) listの各要素の最大値を返します。iteratorが指定されるとlistに各要素にiteratorを実行し,最大値を返します。
_.min(list, [iterator], [context]) listの各要素の最小値を返します。iteratorが指定されるとlistに各要素にiteratorを実行し,最小値を返します。
_.sortBy(list, iterator, [context]) listの各要素を,iteratorが指定されるとlistに各要素にiteratorを実行しその値で,文字列でしたらlistの各要素のpropertyの値と同じ文字列のものでソートします。
_.groupBy(list, iterator, [context])listの各要素を,iteratorが指定されるとlistに各要素にiteratorを実行しその値で,文字列でしたらlistの各要素のpropertyの値と同じ文字列のもので分類します。
_.indexBy(list, iterator, [context]) listの各要素を,iteratorが指定されるとlistに各要素にiteratorを実行しその値で,文字列でしたらlistの各要素のpropertyの値と同じ文字列のものの値をキーにしたlistを返します。
_.countBy(list, iterator, [context]) listの各要素を,iteratorが指定されるとlistに各要素にiteratorを実行しその値で,文字列でしたらlistの各要素のpropertyの値と同じ文字列のもので分類した数を返します。結果の各要素の値は,_.groupBy()の結果の各要素のlengthと同じ値になります。
_.sortedIndex(list, value, [iterator], [context])ソートされたlistに対してvalueの挿入する際のインデックスを返します。
_.shuffle(list) listの各要素を,ランダムに並び替えて返します。
_.sample(list, [n]) listの各要素を,ランダムに抜き出して返します。nで返す要素数を指定できます。
_.toArray(list) listを配列として返します。argumentsオブジェクトにたいてい使われます。

_.each()
書式
_.each(list, iterator, [context])

listの各要素に対してiterator(反復処理を行う関数)を実行します。

iteratorには引数は3つ渡します。引数が配列なら(listの値,listのindex,list)になります。引数がオブジェクトなら(listのプロパティ値,listのプロパティ名,list)になります。引数を1つだけ取るiteratorを記述しても問題ありません。残りの2つは無視されます。ネイティブの機能でforEach()が使える環境ではそちらを使います。

もし [context] オブジェクトが渡されたら,iterator はそれに束縛されます。

下記の例を見ると,iteratorが配列の数の分だけ呼び出されているのがわかります。

_.each( [6,3,1,2], function(val){ alert(val); });
// 6,3,1,2の順でアラート表示されます。

_.each( { six: 6, three: 3, one: 1, two: 2 }, function(val,key,list){ alert('key:' + key + ' val:' + val); });
// key:six val:6,key:three val:3,key:one val:1,key:two val:2の順でアラート表示されます。

_.each()を使うと繰り返しの文がfor文などで表すよりシンプルになり,バグの原因にもなりやすいと言われるループの終了条件の判定などもなくせます。

_.map()
書式
_.map(list, iterator, [context])

_.map()は_.each()と同様に,listの各要素に対してiterator(反復処理を行う関数)を実行します。しかし,_.map()は返ってくる値が_.each()とは異なり,各要素に対してiteratorが返す値を新しい配列として返します。_.map()を使うと配列の変換がシンプルに記述ができます。

ネイティブの機能でmap()が使える環境ではそちらを使います。なお,他の言語ではcollectと呼ばれる場合もあります。

var data = [6,3,1,2];

var data02 = _.map( data, function(val){ return val * 3; });

console.log(data02);
// => [18, 9, 3, 6] 各要素の値に対して3倍した新しい配列が返ります。

var data03 = _.map( {six: 6, three: 3, one: 1, two: 2} , function(val, key){ return val * 3; });

console.log(data03);
// => [18, 9, 3, 6] 各要素に対して3倍した値の配列が返ります。
_.reduce()
書式
_.reduce(list, iterator, memo, [context])

_.reduce()はlistの各要素に対してiteratorを実行し累積結果を返します。これは関数型プログラミングでは普通に行われる処理で,inject,foldと呼ばれることもあります。

iteratorの戻り値は累積結果であり,次の要素に対してiteratorの呼び出しで引数として渡されます。

iteratorの引数は(memo, value)になります。memoが累積結果になります。

ネイティブの機能でreduce()が使える環境ではそちらを使います。

var data = [6,3,1,2];

var product = _.reduce( data, function(memo, value){ return memo*value; }); //値の積
console.log(product);
// => 36

var max = _.reduce( data, function(memo, value){ return (memo > value )? memo : value; }); //値の最大値
console.log(max);
// => 6
_.filter()
書式
_.filter(list, iterator, [context])

listの各要素に対してiteratorを実行し,戻り値が真になる値を抜き出した配列を返します。

ネイティブの機能でfilter()が使える環境ではそちらを使います。

var smallVals = _.filter([1, 2, 3, 4, 5, 6], function(val){ return val < 3; });
console.log(smallVals);
// => [1, 2] 3より少ない値が新しい配列で返ります。
_.every()と_.some()
書式
_.every(list, [iterator], [context])
_.some(list, [iterator], [context])

_.every()と_.some()はlistの各要素に対してiteratorを実行し判定を行います。

_.every()はlistの各要素に対してiteratorを実行し,戻り値がすべて真なら真を,1つでも偽なら偽を返します。

ネイティブの機能でevery()が使える環境ではそちらを使います。

var data = [6,3,1,2];

//すべての値が10より大きい
var result = _.every( data, function(value){ return value < 10 ; });
console.log(result);
// => true

_.some()はlistの各要素に対してiteratorを実行し,戻り値が1つでも真なら真を,すべて偽なら偽を返します。

ネイティブの機能でsome()が使える環境ではそちらを使います。

var data = [6,3,1,2];

//値が偶数を含む
var result = _.some( data, function(value){ return value%2 === 0 ; });
console.log(result);
// => true

著者プロフィール

早瀬まこと(はやせまこと)

大規模Webサイトの運用更新にフロントエンドエ ンジニアとして従事しています。

DOMと組み合わせたフロントエンドの開発を主に行っています。

バックナンバー

Underscore.jsの入り口

コメント

コメントの記入