我知道这是一个旧线程,但我今天遇到了另一个可能受益于另一种方法的实例。我有一个案例,我想使用一个特定的键,这样我就可以抽象出实际的支持功能。这导致使用包装函数找到一个版本,以返回一个匿名函数,该函数利用“使用”命令字提供用于在我的类中排序的键的名称。(在我的情况下,它是 [nested] 类的属性中的一个键,该键被分配给我正在进行排序的类属性之一 - 即我正在根据“维度”实例中的属性对实例进行排序分配给“项目”的属性,并希望能够按宽度、高度、长度或重量对它们进行排序)。然后获取回调函数,
/**
* 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:: 将其称为本地(可以想象,在这种情况下,我什至可以将其包装为非静态函数,因为我唯一担心的是得到调用但函数返回)我很快发现的另一个好处是我的尺寸对象还具有一些“计算”字段,例如周长、体积和体积重量。但一个问题是,尺寸重量取决于您是在国内还是国际运输物品,所以我需要告诉我的“calculateDimensionalWeight”函数它是否应该使用国际运输的价值。好吧,使用这种方法,我可以通过将附加参数传递给包装函数并将附加参数添加到使用变量来做到这一点。
/**
* @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!');
}
注意:以这种方式计算值会产生开销,因为任何列表中除了第一个和最后一个项目之外的所有项目在技术上都将被计算两次,这是多余的,但在这种情况下,我的列表并不长,在某些情况下,我需要在做的时候比较两个项目bin-sorting,所以它仍然是可取的。对于大型数据集,预先计算排序方法外部的值可能更明智。