加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

php – uasort()数组由用户比较函数修改

发布时间:2020-12-13 22:45:48 所属栏目:PHP教程 来源:网络整理
导读:我有一个类,它基本上是一个数组的包装器,并实现了IteratorAggregate. 创建类的新对象时,它会将其值存储在名为$value的受保护变量中.值可以是字符串,整数等.或者是可遍历的对象(如数组). 这个对象是“递归的”,因为当一个可遍历的对象(如数组)传递给构造函数
我有一个类,它基本上是一个数组的包装器,并实现了IteratorAggregate.
创建类的新对象时,它会将其值存储在名为$value的受保护变量中.值可以是字符串,整数等.或者是可遍历的对象(如数组).

这个对象是“递归的”,因为当一个可遍历的对象(如数组)传递给构造函数时,他创建了该类的另一个实例.这是澄清的构造函数:

class ListItem implements IteratorAggregate
{
    protected $readOnly = false;
    protected $key;
    protected $value;

    public function __construct($key,$value,$readOnly = false)
    {
        if($readOnly) $this->readOnly = true;
        if(is_numeric($key)) $key = 'index'.$key;
        $this->key = $key;

        if (is_array($value) || $value instanceof Traversable) {
            $this->value = array();
            foreach($value as $k => $v) {
                if(is_numeric($k)) $k = 'index'.$k;
                $this->value[$k] =  new ListItem($k,$v,$readOnly);
            }
        } else {
            $this->value = $value;
        }
    }

    public function __toString()
    {
        if ( is_array($this->value) ) {
            return 'ListItem OBJECT(' . count($this->value) . ')';
        } else {
            return $this->value;
        }
    }

现在,我正在尝试为类编写一个简单的排序方法.

要按键排序,这就像一个魅力:

$success = ksort($this->value,$comparison);

但是要按值排序,asort不起作用,因为我尝试排序的实际值存储在value属性中.

所以我尝试使用uasort,像这样:

$success = uasort($this->value,function ($a,$b)
   {                    
      if ($a->value == $b->value) return 0;
      else if($a->value < $b->value) return -1;
      else return 1;
   });

但由于一些不明原因,我得到以下错误:

Warning: uasort() [function.uasort]: Array was modified by the user
comparison function in /* /* /* /ListItem.php on line 129

问:如果我只是访问$value进行比较而实际上没有改变任何东西,为什么会发生这种情况呢?

解决方法

似乎闭包(或匿名函数)在全局范围内,这意味着uasort无法访问ListItem对象的私有或受保护成员(尽管其他ListItem对象可以访问其兄弟的私有/受保护属性)

这解决了问题:(铸造到字符串)

$success = uasort($this->value,function ($objA,$objB) use ($comparison)
{
    $a = (string) $objA;
    $b = (string) $objB;
    if($comparison == ListItem::SORT_NUMERIC) {
        if (is_numeric($a)) $a = (int) $a;
        if (is_numeric($b)) $b = (int) $b;
    }                   
    if ($a == $b) return 0;
    else if($a < $b) return -1;
    else return 1;
});

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读