emonkakツイートPHPのコレクション処理ライブラリUnderbar.phpの紹介こんにちわちわ。以前に便利なVimのOperatorをマスターするを書きましたemonkakです。今回は私が個人的に開発を進めていて以前に社内勉強会で発表しました、PHPのコレクション処理ライブラリのUnderbar.phpの紹介をしたいと思います。PHPのarrayなんとか関数は使い勝手が悪いPHPには配列処理のための関数がたくさんありますが、array_map()の引数の順番が変だったりarrayがそもそもオブジェクトではないのでメソッドチェインができなかったり使い勝手が良くありません。6]また、これらの関数はarray専用なので、IteratorのようなTraversableなオブジェクトを引数に取ることはできませんし、処理を遅延してIteratorを返すなんてことも当然できません。そこでarrayとTraversableなオブジェクトを同じように扱えて、Iteratorを利用して遅延リストを返すことができるライブラリが欲しいですよね。PHP5.5から導入されたGeneratorも使えるといいですね!遅延リストの恩恵ここで一度、遅延リストの恩恵について考えてみます。0からの連番をたくさん返すIteratorの$ysがあります。ここから偶数の要素を二乗して5つだけ取り出したいとします。foreachを使って自前でループしてbreakするのが効率的なのは当然ですが、ここでは高階関数を使って書いてみます。64]このコードには効率上の問題が2つあります。要素5つ分のメモリ空間で十分なのにIteratorの長さ分だけ空間を必要とする今回必要としない5個目以降の要素についても$squareが呼びだされてしまう自前でループを書いて処理すればいいのですが面倒ですね。それなら以下のような感じでIteratorをチェインして遅延リストとして処理してしまいましょう。64]これでわざわざループを書かなくても済みますし、効率上の問題も解決しました。Underbar.phpの実装もまさにこのようになっています。Underbar.phpとはUnderbar.phpはこれまでに述べた問題を解決するために開発されたPHPのコレクション処理のためのライブラリです。その名の通りUnderscore.jsにインスパイアされたライブラリですが、移植というわけではないのでそれほど互換性は重要視していません。遅延リストを利用してフィボナッチ数列を10個取り出す例を引用してみます。1,1,2,3,5,8,13,21,34,55今回の例ではIteratorを返すIteratorImplを使っていますが、他にArrayImplとGeneratorImplがあります。その他のPHPのコレクション処理ライブラリ達PHPのarrayが扱いづらい問題はPHPerの共通見解のようでUnderbar.php以外にもいくつかコレクション処理ライブラリが開発されています。大きくUnderscore.js系とLINQ系に分けることができます。anahkiasen)Underscore-Walla-Walla.php自分も1つ増やしてしまったわけですが、ちょっと乱立気味ですね。本来こういった機能は言語の組み込みにするなり、何か統一を図るべきなのかもしれません。まあPHPなのでしょうがないですね!この中だと本家のUnderscore.jsが即時実行する実装なのもあって、遅延実行できる実装はありません。これがUnderbar.phpの最初の開発の動機でした。LINQ系PHPLinqphinqpinqGinqLINQ系のライブラリも結構数がありますが、最後発のGinqが設計が洗練されていて非常に良くできています。このスライドで大体の雰囲気を掴めるかと思います。LINQ好きはGinq使っておけば間違いないですね。Underbar.phpにはないjoinによるデータの結合やソートの合成などもあるのでおすすめです。まとめPHPの配列を扱う関数は非常に使い勝手が悪いので、様々なコレクション処理のためのライブラリが開発されています。中でも遅延リストを扱えるものは少ないので、そういった意味ではUnderbar.phpが選択肢の一つになりうると思います。requestかIssuesの方にお願いします。最後に社内勉強会でのUnderbar.php発表の様子とスライドです。»ブログ記事検索このブログについてこのブログは、札幌市・仙台市の「株式会社インフィニットループ」が運営する技術ブログです。開催されます!【1月25日放送】テレビ北海道(TVh)「けいナビ~応援!どさんこ経済~」に取材いただきました!【中途採用向け】1月21日(火)札幌本社で会社説明会を開催いたします!あけましておめでとうございます!2020年もよろしくお願いいたします。