Asial Blog

Recruit! Asialで一緒に働きませんか?

配列の奥底にある値をもとに配列をソートする

カテゴリ :
バックエンド(プログラミング)
タグ :
Tech
配列
ソート
usort
create_function
こんにちは。松田です。
書くことが思いつかなかったので今回は軽めのネタをひとつ。
phpの連想配列を扱っている時、配列の奥深くにある値をもと配列全体をソートしたい場合があります。
そんなときに使える方法の紹介です。

たとえばこんな配列。
  1. <?php
  2.  
  3. $list = array(
  4.   array('data' => array('data2' => array('value' => 111))),
  5.   array('data' => array('data2' => array('value' => 444))),
  6.   array('data' => array('data2' => array('value' => 333))),
  7.   array('data' => array('data2' => array('value' => 222))),
  8.   array('data' => array('data2' => array('value' => 555))),
  9. );
  10.  
  11. ?>
かなり極端に書いてますが、この配列を value の値でソートしたいとします。

完成後の理想型がこちら。
  1. <?php
  2.  
  3. $list = array(
  4.   array('data' => array('data2' => array('value' => 111))),
  5.   array('data' => array('data2' => array('value' => 222))),
  6.   array('data' => array('data2' => array('value' => 333))),
  7.   array('data' => array('data2' => array('value' => 444))),
  8.   array('data' => array('data2' => array('value' => 555))),
  9. );
  10.  
  11. ?>


こんな場合は、usortとcreate_functionで次のように書きましょう。

  1. <?php
  2.  
  3. usort($list, create_function('$a,$b', 'return $a["data"]["data2"]["value"] > $b["data"]["data2"]["value"];'));
  4.  
  5. ?>
実行後 print_r($list) はこんな感じになります。
  1. Array
  2. (
  3.     [0] => Array
  4.         (
  5.             [data] => Array
  6.                 (
  7.                     [data2] => Array
  8.                         (
  9.                             [value] => 111
  10.                         )
  11.                 )
  12.         )
  13.     [1] => Array
  14.         (
  15.             [data] => Array
  16.                 (
  17.                     [data2] => Array
  18.                         (
  19.                             [value] => 222
  20.                         )
  21.                 )
  22.         )
  23.     [2] => Array
  24.         (
  25.             [data] => Array
  26.                 (
  27.                     [data2] => Array
  28.                         (
  29.                             [value] => 333
  30.                         )
  31.                 )
  32.         )
  33. 長いので以下省略。。

みごとvalueの順に昇順にソートされてますね。


なんとなく予想がつくかもしれませんが、降順にソートする場合は判定式の不等号を逆にしちゃいましょう。

  1. <?php
  2.  
  3. usort($list, create_function('$a,$b', 'return $a["data"]["data2"]["value"] > $b["data"]["data2"]["value"];'));
  4.  
  5. ?>

実行結果。
  1. Array
  2. (
  3.     [0] => Array
  4.         (
  5.             [data] => Array
  6.                 (
  7.                     [data2] => Array
  8.                         (
  9.                             [value] => 555
  10.                         )
  11.                 )
  12.         )
  13.     [1] => Array
  14.         (
  15.             [data] => Array
  16.                 (
  17.                     [data2] => Array
  18.                         (
  19.                             [value] => 444
  20.                         )
  21.                 )
  22.         )
  23. 以下略。。


php5.3以降の場合は無名関数も使えるので、下記のようにかくこともできます。

  1. <?php
  2.  
  3. $func = function($a, $b) { 
  4.   return $a["data"]["data2"]["value"] > $b["data"]["data2"]["value"];
  5. };
  6. usort($list, $func);
  7.  
  8. ?>

判定処理部分をすべて文字列で書かなければいけないcreate_functionよりはこちらのほうがカッコよく書けますね。
こんなふうにusortとcreate_functionは相性がよくなかなか使えます。


・・・とここまで書いたのですが、array_multisortという関数で同じようなことができるようです。。なんてこったい\(^o^)/
お好きな方をどうぞ。。