これが古いスレッドであることは知っていますが、今日、別のアプローチの恩恵を受ける可能性のある別のインスタンスに遭遇しました。実際のサポート機能を抽象化できるように、特定のキーを使用したい場合がありました。これにより、ラッパー関数を使用してバージョンを検索し、「use」コマンドワードを使用して無名関数を返し、クラスでの並べ替えに使用されるキーの名前を指定しました。(私の場合、これは、並べ替えを行っているクラスプロパティの1つに割り当てられている[ネストされた]クラスのプロパティのキーです。つまり、'dimensions'インスタンスのプロパティに基づいてインスタンスを並べ替えています。 'items'のプロパティに割り当てられており、幅、高さ、長さ、重量などで並べ替えることができます。次に、コールバックの関数を取得するには、
/**
* list of items
*
* @var Item[]
*/
public $items;
/**
* @param string $key
* @return \Closure
*/
private static function keySort($key) {
return function ($ia, $ib) use ($key) {
if($ia->dimensions->$key == $ib->dimensions->$key) return 0;
return ($ia->dimensions->$key < $ib->dimensions->$key) ? -1 : 1;
};
}
/**
* return the list of items in the items array sorted by the value
* of the property specified by $key
*
* @param string $key
* @return Item[]
* @throws \Exception
*/
public function sortItemsByKey($key)
{
if(in_array($key, array( 'width', 'length', 'height', 'weight', ))) {
return usort($this->items, static::keySort($key));
} else
throw new \Exception(__METHOD__ . ' invalid sort key!');
}
これにより、static::またはself::のいずれかを使用してローカルで呼び出すことができます(この場合、心配しているのは呼び出しを取得することだけですが、関数が返されるため、非静的関数としてラップすることもできます)私がすぐに発見したもう1つの利点は、寸法オブジェクトにも、周囲長、体積、寸法重量などの「計算された」フィールドがあることです。ただし、問題の1つは、商品を国内または海外に配送するかどうかによって寸法重量が異なるため、「calculateDimensionalWeight」関数に国際配送の値を使用するかどうかを指定する必要があることです。このメソッドを使用すると、ラッパー関数に追加のパラメーターを渡し、use変数に追加のパラメーターを追加するだけでそれを行うことができます。
/**
* @param string $key
* @param bool $intl // only used for dimensional weight
* @return \Closure
*/
private static function keySort($key,$intl=false) {
return function ($ia, $ib) use ($key,$intl) {
switch($key) {
case 'girth':
$ia->dimensions->calculateGirth();
$ib->dimensions->calculateGirth();
break;
case 'dimweight':
$ia->dimensions->calculateDimensionalWeight($intl);
$ib->dimensions->calculateDimensionalWeight($intl);
break;
case 'volume':
$ia->dimensions->calculateVolume();
$ib->dimensions->calculateVolume();
break;
}
if($ia->dimensions->$key == $ib->dimensions->$key) return 0;
return ($ia->dimensions->$key < $ib->dimensions->$key) ? -1 : 1;
};
}
/**
* return the list of items in the items array sorted by the value
*
* @param string $key
* @param bool $intl (only used for dimensional weight sorts on international shipments)
* @return Item[]
* @throws \Exception
*/
public function sortItemsByKey($key,$intl=false)
{
if(in_array($key, array('value','collect', 'width', 'length', 'height', 'weight', 'girth', 'dimweight', 'volume'))) {
return usort($this->items, static::keySort($key,$intl));
} else
throw new \Exception(__METHOD__ . ' invalid sort key!');
}
注:この方法で値を計算すると、リストの最初と最後の項目を除くすべてが技術的に2回計算されるため、オーバーヘッドが発生します。これは冗長ですが、この場合、リストは長くなく、場合によっては、2つの項目を比較する必要があります。ビンソートなので、それでも望ましいです。大規模なデータセットの場合、sortメソッドの外部で値を事前に計算する方がおそらく賢明です。