PHPの無名関数を使って再帰処理を行う
こんにちは、小川です。
今回はSymfonyではなくPHPのお話しです。PHP 5.3から無名関数が使えるようになりました。この無名関数、使い方によっては再帰なプログラムを書くことも可能なのです。
PHPの無名関数は次のようなものです。
無名関数というのは、その名の通り関数名が存在しない関数になります。JavaScriptなどではお馴染みですね。様々な使い方ができると思いますが、よく使うのはコールバック関数として使う方法が挙げられます。
例えばPHPにはarray_mapという標準関数があります。この関数は第1引数にコールバックを、第2引数に配列を指定し、指定した配列の各要素に対して第1引数で指定したコールバックを適応させるためのものです。次の例は、array_mapを利用して配列のそれぞれの要素から母音を取り除くというものです。
その場所でしか使わないような処理のためにわざわざ関数を作るのも面倒ですし、これらの一連の流れがメソッドなどの特定のスコープの中で行われている場合はそのスコープの内部で完結するため、名前空間を汚染せずに済みます。
さて本題の再帰処理です。RubyのArray#flattenと同じようなものを実装してみます。Array#flattenはネストした配列を1次元の配列に平滑化するメソッドです。無名関数にする必要はないですが、再帰のサンプルと言うことで...
先ほどまでと大きく違うのがuseを使用しているところです。useとは、無名関数の外にあるスコープの変数を無名関数内に渡すための仕組みです。関数でいうglobalや、メソッドからオブジェクトのプロパティを参照するようなものです。再帰を行う場合、ここに無名関数を格納する変数への「参照」を渡します。そうでないと、定義されていない変数を渡すことになりエラーになります。
無名関数を活用することで余計な関数やメソッドを定義せずに済んだりもしますが、あまり使いすぎるとそれはそれで可読性の低下につながる可能性もあります。特にPHPで実装されたのは最近の話ですので、見慣れない方もいるでしょう。何事もほどほどに活用していきましょう。
今回はSymfonyではなくPHPのお話しです。PHP 5.3から無名関数が使えるようになりました。この無名関数、使い方によっては再帰なプログラムを書くことも可能なのです。
PHPの無名関数は次のようなものです。
- $greet
= function($name) { echo "Hello, {$name}."; - };
- $greet('fivestar');
#=> Hello, fivestar.
無名関数というのは、その名の通り関数名が存在しない関数になります。JavaScriptなどではお馴染みですね。様々な使い方ができると思いますが、よく使うのはコールバック関数として使う方法が挙げられます。
例えばPHPにはarray_mapという標準関数があります。この関数は第1引数にコールバックを、第2引数に配列を指定し、指定した配列の各要素に対して第1引数で指定したコールバックを適応させるためのものです。次の例は、array_mapを利用して配列のそれぞれの要素から母音を取り除くというものです。
- $array
= array('banana', 'strawberry', 'yudoufu'); - $result
= array_map(function($string) { $vowels = array('a', 'i', 'u', 'e', 'o'); return str_replace($vowels, '', $string); - },
$array); - echo
join(', ', $result); #=> bnn, strwbrry, ydf
その場所でしか使わないような処理のためにわざわざ関数を作るのも面倒ですし、これらの一連の流れがメソッドなどの特定のスコープの中で行われている場合はそのスコープの内部で完結するため、名前空間を汚染せずに済みます。
さて本題の再帰処理です。RubyのArray#flattenと同じようなものを実装してみます。Array#flattenはネストした配列を1次元の配列に平滑化するメソッドです。無名関数にする必要はないですが、再帰のサンプルと言うことで...
- //
use を使って無名関数への参照を渡す - $flatten
= function($array) use(&$flatten) { $result = array(); foreach ($array as $value) { if (is_array($value)) { // 配列ならこの無名関数を再度呼び出す $result = array_merge($result, $flatten($value)); } else { $result[] = $value; } } return $result; - };
- $array
= array(1, 5, array(3, array(22, 5)), 12); - $result
= $flatten($array); - echo
join(', ', $result); #=> 1, 5, 3, 22, 5, 12
先ほどまでと大きく違うのがuseを使用しているところです。useとは、無名関数の外にあるスコープの変数を無名関数内に渡すための仕組みです。関数でいうglobalや、メソッドからオブジェクトのプロパティを参照するようなものです。再帰を行う場合、ここに無名関数を格納する変数への「参照」を渡します。そうでないと、定義されていない変数を渡すことになりエラーになります。
無名関数を活用することで余計な関数やメソッドを定義せずに済んだりもしますが、あまり使いすぎるとそれはそれで可読性の低下につながる可能性もあります。特にPHPで実装されたのは最近の話ですので、見慣れない方もいるでしょう。何事もほどほどに活用していきましょう。
コメントフォーム
トラックバック
-
- RecursiveIteratorIteratorIteratorIterator from 例えば、PHPを使う
- (※画像はI love unicodeの人のスライドCode, Ideas, People」からの借用です。) ...
2010年03月26日 00:41
最近の記事
- もうすぐ健康診断があるんだ・・・ [2010年09月02日 : 阿部恵]
- Photoshopで壁紙を作りながら、基本的な使い方を覚える [2010年09月01日 : 鴨田健次]
- はじめての共同作業 Canvas編 (node.js + websocket) [2010年09月01日 : 中川善樹]
- 「PHP×Flex(後編)」PHPテクニカルセミナー(無料)第4弾の募集を開始しました!! [2010年08月26日 : 和田記光]
- 【HTML5】Canvasでお絵かきしてみた(前編) [2010年08月25日 : 橋本章史]
- MacにgroongaのMySQL用ストレージエンジン [2010年08月23日 : 笹亀弘]
- Appleのサイトで見たiPhone4をFireworksで描いてみました-1/2 [2010年08月19日 : 和田記光]
- iPad版の会社紹介を作ってみました [2010年08月19日 : 小林有佳]
- iPhoneアプリ開発開始時に気をつけるべきファイルの取り扱い (2) [2010年08月19日 : 亀本大地]
- symfonyセミナー動画無料公開! [2010年08月13日 : 岡本雄樹]



最近のコメント