2008-09-23 47 views
42

Cách thanh lịch để sắp xếp các đối tượng trong PHP là gì? Tôi rất muốn thực hiện một cái gì đó tương tự như thế này.Sắp xếp đối tượng trong PHP

$sortedObjectArary = sort($unsortedObjectArray, $Object->weight); 

Về cơ bản chỉ định mảng tôi muốn sắp xếp cũng như trường tôi muốn sắp xếp. Tôi nhìn vào phân loại mảng đa chiều và có thể có một cái gì đó hữu ích ở đó, nhưng tôi không thấy bất cứ điều gì tao nhã hay rõ ràng.

Trả lời

73

Hầu như nguyên văn từ hướng dẫn:

function compare_weights($a, $b) { 
    if($a->weight == $b->weight) { 
     return 0; 
    } 
    return ($a->weight < $b->weight) ? -1 : 1; 
} 

usort($unsortedObjectArray, 'compare_weights'); 

Nếu bạn muốn đối tượng để có thể sắp xếp bản thân, xem ví dụ 3 ở đây: http://php.net/usort

+0

Đó Ví dụ thứ ba là về cơ bản nói, "Xin lỗi không có cách nào tiêu chuẩn cho một đối tượng để có một so sánh, chỉ cần viết một hàm tĩnh 'cmp_obj' trong đối tượng, và nhớ gọi usort với hàm đó." Được rồi, ngoại trừ cmp_obj đó không có ý nghĩa đặc biệt trong PHP. Có lẽ điều đó sẽ hữu ích nếu PHP có một cái gì đó giống như hàm '__cmp__' của Python như là tiêu chuẩn, hoặc giao diện' thực hiện so sánh 'của Java để nó có thể sắp xếp và sử dụng '<', '>', các bộ so sánh mà không đi sâu vào bất kỳ việc thực hiện nào của lớp muốn sắp xếp. Thật không may có vẻ như điều này cũng không thay đổi trong PHP7. – NoBugs

+1

Bây giờ, điều đó sẽ làm cho PHP trở nên hợp lý và có thể sử dụng được, không thể có chúng ta? :) –

+0

Không, chúng tôi không thể, nhưng chúng tôi thực sự cần một cách khác để thể hiện cùng một biểu thức trong PHP7 mặc dù https://wiki.php.net/rfc/combined-comparison-operator – NoBugs

2

Chức năng usort (http://uk.php.net/manual/en/function.usort.php) là bạn của bạn. Một cái gì đó như ...

function objectWeightSort($lhs, $rhs) 
{ 
    if ($lhs->weight == $rhs->weight) 
    return 0; 

    if ($lhs->weight > $rhs->weight) 
    return 1; 

    return -1; 
} 

usort($unsortedObjectArray, "objectWeightSort"); 

Lưu ý rằng mọi phím mảng sẽ bị mất.

1

Bạn có thể sử dụng chức năng usort() và thực hiện chức năng so sánh của riêng bạn.

$sortedObjectArray = usort($unsortedObjectArray, 'sort_by_weight'); 

function sort_by_weight($a, $b) { 
    if ($a->weight == $b->weight) { 
     return 0; 
    } else if ($a->weight < $b->weight) { 
     return -1; 
    } else { 
     return 1; 
    } 
} 
5

Bạn thậm chí có thể xây dựng các hành vi sắp xếp vào lớp học mà bạn đang phân loại, nếu bạn muốn mức độ kiểm soát đó

class thingy 
{ 
    public $prop1; 
    public $prop2; 

    static $sortKey; 

    public function __construct($prop1, $prop2) 
    { 
     $this->prop1 = $prop1; 
     $this->prop2 = $prop2; 
    } 

    public static function sorter($a, $b) 
    { 
     return strcasecmp($a->{self::$sortKey}, $b->{self::$sortKey}); 
    } 

    public static function sortByProp(&$collection, $prop) 
    { 
     self::$sortKey = $prop; 
     usort($collection, array(__CLASS__, 'sorter')); 
    } 

} 

$thingies = array(
     new thingy('red', 'blue') 
    , new thingy('apple', 'orange') 
    , new thingy('black', 'white') 
    , new thingy('democrat', 'republican') 
); 

print_r($thingies); 

thingy::sortByProp($thingies, 'prop1'); 

print_r($thingies); 

thingy::sortByProp($thingies, 'prop2'); 

print_r($thingies); 
+0

Giải pháp này không hoạt động trong PHP4. – Lobo

+18

@Lobo PHP 5 đã 4 tuổi vào thời điểm tôi viết bài này, cách đây 4 năm. Tôi nghĩ sau 8 năm, chúng tôi có thể đưa PHP4 ra đồng cỏ một cách an toàn. –

0

Tùy thuộc vào sự cố bạn đang cố giải quyết, bạn cũng có thể thấy giao diện SPL hữu ích. Ví dụ, việc thực hiện giao diện ArrayAccess sẽ cho phép bạn truy cập vào lớp của bạn như một mảng. Ngoài ra, việc triển khai giao diện SeekableIterator sẽ cho phép bạn lặp qua đối tượng của mình giống như một mảng. Bằng cách này bạn có thể sắp xếp đối tượng của mình giống như là một mảng đơn giản, có toàn quyền kiểm soát các giá trị mà nó trả về cho một khóa đã cho.

Để biết thêm chi tiết:

20

Đối với php> = 5,3

function osort(&$array, $prop) 
{ 
    usort($array, function($a, $b) use ($prop) { 
     return $a->$prop > $b->$prop ? 1 : -1; 
    }); 
} 

Lưu ý rằng đây sử dụng Ano các chức năng/đóng cửa nymous. Có thể tìm thấy xem xét các tài liệu php trên đó hữu ích.

+1

Điều gì xảy ra nếu '$ a -> $ prop == $ b -> $ prop'? –

4

Cho rằng so sánh chức năng, bạn chỉ có thể làm:

function cmp($a, $b) 
{ 
    return $b->weight - $a->weight; 
} 
0
function PHPArrayObjectSorter($array,$sortBy,$direction='asc') 
{ 
    $sortedArray=array(); 
    $tmpArray=array(); 
    foreach($this->$array as $obj) 
    { 
     $tmpArray[]=$obj->$sortBy; 
    } 
    if($direction=='asc'){ 
     asort($tmpArray); 
    }else{ 
     arsort($tmpArray); 
    } 

    foreach($tmpArray as $k=>$tmp){ 
     $sortedArray[]=$array[$k]; 
    } 

    return $sortedArray; 

} 

e.g =>

$myAscSortedArrayObject=PHPArrayObjectSorter($unsortedarray,$totalMarks,'asc'); 

$myDescSortedArrayObject=PHPArrayObjectSorter($unsortedarray,$totalMarks,'desc'); 
0

Bạn có thể có hầu hết các mã giống như bạn được đăng với sorted chức năng từ Nspl:

use function \nspl\a\sorted; 
use function \nspl\op\propertyGetter; 
use function \nspl\op\methodCaller; 

// Sort by property value 
$sortedByWeight = sorted($objects, propertyGetter('weight')); 

// Or sort by result of method call 
$sortedByWeight = sorted($objects, methodCaller('getWeight')); 
Các vấn đề liên quan