开发者

PHP: I have an associative array (int => object), want to sort it

class DownTime {
    public $total, $longest, $count;
}

I have an associative array (key is an id, value is DownTime object).

I want to sort it according to $total

I've read PHP: Sorting Arrays and some other questions on stackoverflow.

I understand uasort will do the job fine. However, as an OOP approach, I would prefer define a special function (like defining operator<() in C++, or implementing Comparable.compareTo() in Jav开发者_C百科a) inside the DownTime class, rather than passing a function when calling some sort function.


You can define a compare() method on the DownTime class:

class DownTime {
    public $total, $longest, $count;
    public static function compare(DownTime $a, DownTime $b) {
        // compare $a and $b here, and return -1, 0, 1
    }
}

Then use uasort like this:

uasort($array, 'DownTime::compare')

There is no such "Comparable" interface in PHP, however it would be quite simple to implement it in useland :

interface Comparable {
    function compareTo($a);
}

// a generic compare function
function compare($a, $b) {
    if ($a instanceof Comparable) return $a->compareTo($b);
    if ($a < $b) return -1;
    if ($a > $b) return 1;
    return 0;
}

// now you can sort without knowing anything about what the array contains:
uasort($array, 'compare');

And if you want to be able to do this transparently with an ArrayObject:

class SortableArrayObject extends ArrayObject
{
    function asort() {
        return $this->uasort('compare'); // you can even make compare() a member of
                                         // SortableArrayObject and use 
                                         // $this->uasort(array($this,'compare'))
    }
}

$arrayObject->asort();

Here the container knows nothing about the containee, which is better in a OOP point of view.


The other option while still using the language is to create an iterator collection class that extends Iterator instead of using a native array.

Actually, you can also extend ArrayObject and override the sort methods:

class MyArrayObject extends ArrayObject {
    public function natsort() {
        $this->uasort(function($a, $b) {
            return $a->total > $b->total ? 1 : -1;
        });
    }
}

$arrayObject = new MyArrayObject($array);
$arrayObject->natsort();

foreach ($arrayObject as $value) {
    //sorted values
}

Or if you really need a native array after that:

$array = $arrayObject->getArrayCopy();

But I find that I usually don't need native arrays where I use iterators/arrayobjects.

Just another alternative to a compare function on the class itself...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜