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で実装されたのは最近の話ですので、見慣れない方もいるでしょう。何事もほどほどに活用していきましょう。
トラックバックURI
-
- RecursiveIteratorIteratorIteratorIterator from 例えば、PHPを使う
- (※画像はI love unicodeの人のスライドCode, Ideas, People」からの借用です。) ...
2010年03月26日 00:41
最近の記事
システム開発エンジニア募集! [2012年02月03日 : 小林有佳]
OpenVPNで細々便利な設定 [2012年01月31日 : 門脇優児]
【iOS】Viewの開発・デバッグに役立つ色々 [2012年01月23日 : 中川善樹]
PHPDocumentorの利用方法まとめ [2012年01月19日 : 笹亀弘]
Google Chart Toolsを使ってサイトマップを描こう! [2011年12月21日 : 志田仁美]
stumpwm設定v2 [2011年12月19日 : 門脇優児]
Mashup Awards 7の授賞式が行われました [2011年12月16日 : 中川善樹]
社員旅行に行きました [2011年12月12日 : 大橋寛子]
iCloud風のアイコンを作成する(Fireworks) [2011年12月07日 : 和田記光]
iScroll4でネイティブに近いスマホ向けHTMLページを作成する [2011年12月02日 : 松田惇]













コメントフォーム