SDC*_*SDC 7 php arrays sorting usort
这里有很多问题,询问如何在PHP中对多维数组进行排序.答案是usort().我知道.但是我有一个问题需要更进一步,我在这里看不到类似的答案.
我有一系列记录,每个记录都包含一个国家ID(如果您愿意,可以是国家/地区名称;它不相关).
我的任务是以有利于某些国家的方式对阵列进行排序.这是动态的 - 即支持的国家的选择取决于用户的配置.我有一个单独的数组,它指定了前几个国家所需的排序顺序; 来自其他国家的结果只会在列表末尾未分类.
所以问题是:如何在usort()不使用全局变量的情况下获得此排序标准.并且最好不要将条件数组注入到主数组的每个元素中('如果我还要循环它,那么,使用它的重点是什么usort()?)
请注意:由于它与这里的答案相关,我暂时停留在PHP 5.2上,所以我不能使用匿名函数.我们正在升级,但是现在我需要能够解决5.2的问题.(5.3/5.4的答案也会受到欢迎,特别是如果它们使它变得更容易,但我将无法使用它们)
你明确地写道,你不想拥有全局变量,所以我不会给你一个静态变量的建议,因为那些实际上是全局变量 - 根本不需要那些变量.
在PHP 5.2(及更早版本)中,如果您需要回调中的调用上下文,您可以通过使用它自己的类来创建您的上下文:
class CallContext
{
}
Run Code Online (Sandbox Code Playgroud)
例如,您有以下比较功能sort:
class CallContext
{
...
public function compare($a, $b)
{
return $this->weight($a) - $this->weight($b);
}
public function getCallback()
{
return array($this, 'compare');
}
...
}
Run Code Online (Sandbox Code Playgroud)
该函数可以用作以下的回调usort:
$context = new CallContext();
usort($array, $context->getCallback());
Run Code Online (Sandbox Code Playgroud)
挺直的.私人实施CallContext::weight仍然缺失,从您的问题我们知道它需要一些数据和信息.例如,每条记录中国家/地区ID的密钥名称.假设记录是Stdclass对象,因此要获取一个记录的权重,上下文类需要知道属性的名称,您自己定义的排序顺序以及未在其中定义的那些country-id的排序值.自定义排序顺序(其他,其余).
这些配置值使用构造函数(简称ctor)给出,并存储为私有成员.丢失的weight函数然后根据该信息将记录转换为排序值:
class CallContext
{
private $property, $sortOrder, $sortOther;
public function __construct($property, $sortOrder, $sortOther = 9999)
{
$this->property = $property;
$this->sortOrder = $sortOrder;
$this->sortOther = $sortOther;
}
private function weight($object) {
if (!is_object($object)) {
throw new InvalidArgumentException(sprintf('Not an object: %s.', print_r($object, 1)));
}
if (!isset($object->{$this->property})) {
throw new InvalidArgumentException(sprintf('Property "%s" not found in object: %s.', $this->property, print_r($object, 1)));
}
$value = $object->{$this->property};
return isset($this->sortOrder[$value])
? $this->sortOrder[$value]
: $this->sortOther;
}
...
Run Code Online (Sandbox Code Playgroud)
用法现在扩展到以下内容:
$property = 'country';
$order = array(
# country ID => sort key (lower is first)
46 => 1,
45 => 2
);
$context = new CallContext('country', $order);
usort($array, $context->getCallback());
Run Code Online (Sandbox Code Playgroud)
使用相同的原则,您可以经常将带有use子句的任何PHP 5.3闭包转换为PHP 5.2.该use条款中的变量成为注入构造的私有成员.
这个变体不仅可以防止静态的使用,而且还可以看出每个元素都有一些映射,并且两个元素都被视为相等,它使用了一些weight非常适合的函数的私有实现usort.
我希望这是有帮助的.
| 归档时间: |
|
| 查看次数: |
1107 次 |
| 最近记录: |