Util

Arrays (配列操作)

Author : trashtoy

Table of Contents

Arrays クラスの概要

Peach_Util_Arrays は, 配列のソートや最大値・最小値の取得など, 配列操作に関する汎用処理を集めたユーティリティクラスです.

オブジェクトの配列をソートする

オブジェクトを含んだ配列をソートするための方法として, 一般的に usort が利用されますが, このモジュールでは Java のコレクション・フレームワークのようなオブジェクト指向的なソート API を使うことができます. オブジェクトの配列をソートする際に利用する Peach_Util_Comparator および Peach_Util_Comparable は, それぞれ java.util.Comparator, java.lang.Comparable と同じような使い方をします.

Peach_Util_Comparable の使用例

Peach_Util_Comparable を使ったソートの例を以下に示します. ソート対象のクラスで implements Peach_Util_Comparable を宣言して, compareTo() メソッド内にソート条件を定義します.

  1. class TestObject implements Peach_Util_Comparable
  2. {
  3.     private $id;
  4.     private $value;
  5.  
  6.     public function __construct($id$value)
  7.     {
  8.         $this->id    $id;
  9.         $this->value $value;
  10.     }
  11.  
  12.     public function getId()
  13.     {
  14.         return $this->id;
  15.     }
  16.  
  17.     public function getValue()
  18.     {
  19.         return $this->value;
  20.     }
  21.  
  22.     /**
  23.      * 引数の TestObject の value を比較します.
  24.      * value が等しい場合は id を比較します.
  25.      */
  26.     public function compareTo($subject)
  27.     {
  28.         if ($subject instanceof TestObject{
  29.             $comp $this->value $subject->value;
  30.             if ($compreturn 1;
  31.             if ($comp 0return -1;
  32.  
  33.             $comp2 $this->id $subject->id;
  34.             if ($comp2return 1;
  35.             if ($comp2 0return -1;
  36.  
  37.             return 0;
  38.         else {
  39.             throw new Exception();
  40.         }}
  41. }
  42.  
  43. $arr array(
  44.     new TestObject(1250),
  45.     new TestObject(5100),
  46.     new TestObject(4400),
  47.     new TestObject(3320),
  48.     new TestObject(2400)
  49. );
  50.  
  51. $arr Peach_Util_Arrays::sort($arr)// => ID が 5, 1, 3, 2, 4 の順にソートされる

Peach_Util_Comparator の使用例

Peach_Util_Comparable を使った例では既存のクラスに手を加えることでソートを実装しましたが, 他者が公開したクラスライブラリのように自由に改変することが難しいクラスをソートする場合や, ソート条件を状況に応じて柔軟に切り替えたい場合には Peach_Util_Comparator を使ってください. Peach_Util_Comparator を使ったソートの例を以下に示します. この例では一つの配列に対して, 4種類の Comparator を使ってソートを行います. それぞれ別の順序でソートされることに着目してください.

  1. class TestObject
  2. {
  3.     private $id;
  4.     private $value;
  5.  
  6.     public function __construct($id$value)
  7.     {
  8.         $this->id    $id;
  9.         $this->value $value;
  10.     }
  11.  
  12.     public function getId()
  13.     {
  14.         return $this->id;
  15.     }
  16.  
  17.     public function getValue()
  18.     {
  19.         return $this->value;
  20.     }
  21. }
  22.  
  23. /**
  24.  * 1.value 昇順, 2.ID 昇順の順番でソートします
  25.  */
  26. class TestObjectComparator1 implements Peach_Util_Comparator
  27. {
  28.     public function compare($var1$var2)
  29.     {
  30.         if (($var1 instanceof TestObject&& ($var2 instanceof TestObject)) {
  31.             $comp $var1->getValue($var2->getValue();
  32.             if ($compreturn 1;
  33.             if ($comp 0return -1;
  34.  
  35.             $comp2 $var1->getId($var2->getId();
  36.             if ($comp2return 1;
  37.             if ($comp2 0return -1;
  38.  
  39.             return 0;
  40.         else {
  41.             throw new Exception();
  42.         }}
  43. }
  44.  
  45. /**
  46.  * 1.ID 昇順, 2.value 昇順の順番でソートします
  47.  */
  48. class TestObjectComparator2 implements Peach_Util_Comparator
  49. {
  50.     public function compare($var1$var2)
  51.     {
  52.         if (($var1 instanceof TestObject&& ($var2 instanceof TestObject)) {
  53.             $comp $var1->getId($var2->getId();
  54.             if ($compreturn 1;
  55.             if ($comp 0return -1;
  56.  
  57.             $comp2 $var1->getValue($var2->getValue();
  58.             if ($comp2return 1;
  59.             if ($comp2 0return -1;
  60.  
  61.             return 0;
  62.         else {
  63.             throw new Exception();
  64.         }}
  65. }
  66.  
  67. $c1 new TestObjectComparator1();
  68. $c2 new TestObjectComparator2();
  69.  
  70. $arr array(
  71.     new TestObject(5100),
  72.     new TestObject(3300),
  73.     new TestObject(2100),
  74.     new TestObject(4200),
  75.     new TestObject(1300)
  76. );
  77.  
  78. $result1 Peach_Util_Arrays::sort($arr$c1)// ID(value) が 2(100), 5(100), 4(200), 1(300), 3(300) の順にソート
  79. $result2 Peach_Util_Arrays::sort($arr$c2)// ID が 1, 2, 3, 4, 5 の順にソート

max, min の活用方法

配列の中から最大 (あるいは最小) の項目を抜き出すというケースはよくありますが, 普通は

  1. 配列をソートする
  2. 配列の先頭 (あるいは末尾) の項目を取り出す

という手順で実現されることが多いです.

そのようなケースでは Peach_Util_Arrays::max() あるいは Peach_Util_Arrays::min() を使うことで簡単に最大・最小値を取り出すことが出来ます.

(数値の配列から最大・最小値を取り出す場合はビルトイン関数の min(), max() を使ってください. ただし, パフォーマンスは劣りますが Peach_Util_Arrays::max(), Peach_Util_Arrays::min() でも同様の結果を得られます.)

  1. class TestObject implements Peach_Util_Comparable
  2. {
  3.     // (中略)
  4. }
  5.  
  6. $arr array(
  7.     new TestObject(1250),
  8.     new TestObject(5100),
  9.     new TestObject(4400),
  10.     new TestObject(3320),
  11.     new TestObject(2400)
  12. );
  13.  
  14. $max Peach_Util_Arrays::max($arr)// => ID = 4, value = 400 のオブジェクトを取得する