PHPerなら多くの方が利用しているLaravel、そのLaravelで配列を便利に扱えるクラスといえばCollectionですね!自分もPHPerでJS等のフロントよりの作業もたまにありますが、JavaScriptで配列を扱うのが苦手でした。
ですが、JavaScriptでもこのLaravelのCollectionのように配列を扱えるcollect.jsというものと出会えたので試してみることにしました。
導入(Installation)
まずはcollect.jsを使える状態にします。
npmだと以下のようにインストールします。
$ npm install collect.js --save
yarnだとこのようになります。
$ yarn add collect.js
HTMLファイルなどのCDNから取得する場合はhttps://cdnjs.com/libraries/collect.js
から取得するようです。それを<script>
タグで指定します。
今回この記事で動作確認するために、実行環境がブラウザと楽なため、htmlでmin.jsファイルで4.36.1を指定して利用してみることにします。
<script src="https://cdnjs.cloudflare.com/ajax/libs/collect.js/4.36.1/collect.min.js"></script>
このようなtest.htmlファイルを作成してchrome等のブラウザで開き、developer toolsでconsoleを開いて実行してみることにします。
このように真っ白なページだけど、collect.jsを楽に扱えるようになりました。
collect.jsのいろんなメソッドを利用してみる
では早速いろんなメソッドを見ていきたいと思います。
まずはじめに、配列の生成と出力を見ていきたいと思います。
今回はtimesを利用して配列を生成するのを基本的な形としてみます。生成された配列を出力するときはdump()やdd()やall()等を利用するとarrayやオブジェクトとして出力されてしまうため、toJson()で文字列出力して記事に貼り付けていきます。
コピペしやすいようにtoJson()で文字列化。
collect().times(10, n => n).toJson()
'[1,2,3,4,5,6,7,8,9,10]'
このようにスクリプトと実行結果を載せる形で紹介していきます。
dump()とdd()とall()とtoArray()
toJson()を使いますと書いておきつつ、とりあえず基本的な出力のメソッドを確認しておきます。dump()
とdd()
とall()
とtoArray()
です。
dump()
dump()はcollectionを出力しつつ、自分自身を返すため、コンソール上に同じものが2度出力されます。
dd()
dd()は処理をとめてしまうので、ブラウザ上だとエラーになってしまいます。ただ、dump()と同じようにオブジェクトを出力できました。
all()
all()は要素を配列として出力してくれます。
toArray()
toArray()も要素を配列として変換してくれます。
all()とtoArray()の違い
では、all()とtoArray()の違いはなんでしょうか?どちらも配列に変換しているだけに見えます。
わかりやすい例として、多次元の配列のコレクションを用意してみました。
このようにtoArray()は要素の中身も再帰的に配列に変換していることがわかります。これはLaravelのall()とtoArray()の挙動と同じですね。
each()
まずは基本的なループ関数のeach()から見ていきましょうか。
let sum = 0
collect().times(10, n => n).each(item => sum += item)
55
このようにeachでぐるぐる回して合計値を求めることができました。
map()
次にループしつつ値を返してくれるmap()を見ていきましょう。
collect().times(10, n => n).map(item => item * 2).toJson() [2,4,6,8,10,12,14,16,18,20]
map()を利用して配列のすべての要素を2倍にすることができました。
filter()
次にfilter()でフィルタリングしていきます。
collect().times(10, n => n).filter(n => n % 2 == 0).toJson()
'[2,4,6,8,10]'
偶数のときだけtrueになる条件を書き、ちゃんと偶数だけを抽出できました。
reject()
filter()をやったということは次はreject()ですね。
collect().times(10, n => n).reject(n => n % 2 == 0).toJson()
'[1,3,5,7,9]'
偶数を除外したので奇数だけが残りました。
first()
要素の一番最初のものを取り出すfirst()です。
collect().times(10, n => n).first() 1
last()
逆に最後の要素を取り出してみます。
collect().times(10, n => n).last() 10
pop()
次にpopしてみます。
let collection = collect().times(10, n => n) collection.pop(); // 10を返す collection.toJson() '[1,2,3,4,5,6,7,8,9]'
keyBy()
次にkeyBy()してみます。
collect().times(10, n => n).map(item => [item, item * 2]).keyBy(item => item[0]).toJson() '{"1":[1,2],"2":[2,4],"3":[3,6],"4":[4,8],"5":[5,10],"6":[6,12],"7":[7,14],"8":[8,16],"9":[9,18],"10":[10,20]}'
わかりにくいですが、要素番号でkeyBy()してます。
get()
上のkeyByしたものに対してget()をしてみます。
collect().times(10, n => n).map(item => [item, item * 2]).keyBy(item => item[0]).get(4) (2) [4, 8]
has()
先程のkeyByしたものに対してhas()で存在チェックをしてみます。
collect().times(10, n => n).map(item => [item, item * 2]).keyBy(item => item[0]).has(4) true collect().times(10, n => n).map(item => [item, item * 2]).keyBy(item => item[0]).has(40) false
まとめ
他にもたくさんのメソッドが用意されていますが、全て試していると一生記事が完成しないんじゃないかという不安になり、途中で止めてしまいました。
ここまで試したものはLaravelのCollectionと同じ動作をしてくれることが確認できました。また、今回確認していないものもドキュメントの実行例などを確認するとLaravelのCollectionと同じ書き方で利用することがわかります。
もし、今後JavaScriptで配列を扱うことが多くなりそうであれば、このcollect.jsを思い出して導入を検討したいなって思えました。PHPer(Laraveler)の方なら気持ちがわかってくれるはず!