Hướng dẫn dùng sorted map trong PHP

Mảng một chiều cơ bản

$array = array(3, 5, 2, 8);

Các hàm sắp xếp áp dụng:

Nội dung chính

  • Mảng một chiều cơ bản
  • Mảng đa chiều, bao gồm mảng đối tượng
  • sort sắp xếp theo tham chiếu và không trả lại bất cứ điều gì hữu ích!
  • So sánh số tùy chỉnh
  • Các đối tượng
  • Chức năng
  • Người điều khiển tàu vũ trụ
  • Sắp xếp theo nhiều lĩnh vực
  • Sắp xếp vào một hướng dẫn, trật tự tĩnh
  • Sắp xếp một mảng dựa trên mảng khác

Nội dung chính

  • Mảng một chiều cơ bản
  • Mảng đa chiều, bao gồm mảng đối tượng
  • sort sắp xếp theo tham chiếu và không trả lại bất cứ điều gì hữu ích!
  • So sánh số tùy chỉnh
  • Các đối tượng
  • Chức năng
  • Người điều khiển tàu vũ trụ
  • Sắp xếp theo nhiều lĩnh vực
  • Sắp xếp vào một hướng dẫn, trật tự tĩnh
  • Sắp xếp một mảng dựa trên mảng khác
  • sort
  • rsort
  • asort
  • arsort
  • natsort
  • natcasesort
  • ksort
  • krsort

Sự khác biệt giữa chúng chỉ đơn thuần là liệu các liên kết giá trị khóa được giữ (các ahàm ""), cho dù nó sắp xếp từ thấp đến cao hoặc đảo ngược (" r"), cho dù nó sắp xếp các giá trị hoặc khóa (" k") và cách so sánh các giá trị (" nat" so với bình thường). Xem http://php.net/manual/en/array.sorting.php để biết tổng quan và liên kết đến các chi tiết khác.

Mảng đa chiều, bao gồm mảng đối tượng

$array = array(
    array('foo' => 'bar', 'baz' => 42),
    array('foo' => ...,   'baz' => ...),
    ...
);

Nếu bạn muốn sắp xếp $arraytheo khóa 'foo' của mỗi mục, bạn cần có chức năng so sánh tùy chỉnh . Các hàm trên sortvà các hàm liên quan hoạt động trên các giá trị đơn giản mà chúng biết cách so sánh và sắp xếp. PHP không chỉ đơn giản là "biết" phải làm gì với một giá trị phức tạp như thế array('foo' => 'bar', 'baz' => 42); Vì vậy, bạn cần phải nói với nó.

Để làm điều đó, bạn cần tạo một chức năng so sánh . Hàm đó có hai phần tử và phải trả về 0nếu các phần tử này được coi là bằng nhau, giá trị thấp hơn 0nếu giá trị đầu tiên thấp hơn và giá trị cao hơn 0nếu giá trị đầu tiên cao hơn. Đó là tất cả những gì cần thiết:

function cmp(array $a, array $b) {
    if ($a['foo'] < $b['foo']) {
        return -1;
    } else if ($a['foo'] > $b['foo']) {
        return 1;
    } else {
        return 0;
    }
}

Thông thường, bạn sẽ muốn sử dụng một chức năng ẩn danh làm cuộc gọi lại. Nếu bạn muốn sử dụng một phương thức hoặc phương thức tĩnh, hãy xem các cách khác để chỉ định một cuộc gọi lại trong PHP .

Sau đó, bạn sử dụng một trong các chức năng sau:

  • usort
  • uasort
  • uksort

Một lần nữa, chúng chỉ khác nhau ở chỗ chúng giữ các liên kết khóa-giá trị và sắp xếp theo giá trị hoặc khóa. Đọc tài liệu của họ để biết chi tiết.

Ví dụ sử dụng:

usort($array, 'cmp');

usortsẽ lấy hai mục từ mảng và gọi cmphàm của bạn với chúng. Vì vậy, cmp()sẽ được gọi với $atheo array('foo' => 'bar', 'baz' => 42)$bnhư nhau array('foo' => ..., 'baz' => ...). Hàm sau đó trả về usortgiá trị nào lớn hơn hoặc chúng có bằng nhau không. usortlặp lại quá trình này thông qua các giá trị khác nhau cho $a$bcho đến khi mảng được sắp xếp. Các cmpchức năng sẽ được gọi nhiều lần, ít nhất là nhiều lần như có giá trị trong $array, với sự kết hợp khác nhau của các giá trị cho $a$bmỗi lần.

Để làm quen với ý tưởng này, hãy thử điều này:

function cmp($a, $b) {
    echo 'cmp called with $a:', PHP_EOL;
    var_dump($a);
    echo 'and $b:', PHP_EOL;
    var_dump($b);
}

Tất cả những gì bạn đã làm là xác định một cách tùy chỉnh để so sánh hai mục, đó là tất cả những gì bạn cần. Điều đó làm việc với tất cả các loại giá trị.

Nhân tiện, điều này hoạt động trên bất kỳ giá trị nào, các giá trị không phải là mảng phức tạp. Nếu bạn có một so sánh tùy chỉnh bạn muốn làm, bạn cũng có thể làm điều đó trên một mảng số đơn giản.

sort sắp xếp theo tham chiếu và không trả lại bất cứ điều gì hữu ích!

Lưu ý rằng các mảng sắp xếp tại chỗ , bạn không cần gán giá trị trả về cho bất cứ điều gì. $array = sort($array)sẽ thay thế mảng bằng true, không phải bằng một mảng được sắp xếp. Chỉ cần sort($array);làm việc.

So sánh số tùy chỉnh

Nếu bạn muốn sắp xếp theo bazkhóa, đó là số, tất cả những gì bạn cần làm là:

function cmp(array $a, array $b) {
    return $a['baz'] - $b['baz'];
}

Nhờ vào PoCHr oF MATH, điều này trả về giá trị <0, 0 hoặc> 0 tùy thuộc vào việc $acó thấp hơn, bằng hoặc lớn hơn $b.

Lưu ý rằng điều này sẽ không hoạt động tốt cho floatcác giá trị, vì chúng sẽ bị giảm xuống intvà mất độ chính xác. Sử dụng rõ ràng -1, 01trả về giá trị thay thế.

Các đối tượng

Nếu bạn có một mảng các đối tượng, nó hoạt động theo cùng một cách:

function cmp($a, $b) {
    return $a->baz - $b->baz;
}

Chức năng

Bạn có thể làm bất cứ điều gì bạn cần trong một chức năng so sánh, bao gồm các chức năng gọi:

function cmp(array $a, array $b) {
    return someFunction($a['baz']) - someFunction($b['baz']);
}

Dây

Một lối tắt cho phiên bản so sánh chuỗi đầu tiên:

function cmp(array $a, array $b) {
    return strcmp($a['foo'], $b['foo']);
}

strcmpkhông chính xác những gì mong đợi cmpở đây, nó trả lại -1, 0hoặc 1.

Người điều khiển tàu vũ trụ

PHP 7 đã giới thiệu toán tử tàu vũ trụ , hợp nhất và đơn giản hóa bằng / nhỏ hơn / lớn hơn so với các so sánh giữa các loại:

function cmp(array $a, array $b) {
    return $a['foo'] <=> $b['foo'];
}

Sắp xếp theo nhiều lĩnh vực

Nếu bạn muốn sắp xếp chủ yếu theo foo, nhưng nếu foobằng nhau cho hai yếu tố sắp xếp theo baz:

function cmp(array $a, array $b) {
    if (($cmp = strcmp($a['foo'], $b['foo'])) !== 0) {
        return $cmp;
    } else {
        return $a['baz'] - $b['baz'];
    }
}

Đối với những người quen thuộc, điều này tương đương với một truy vấn SQL với ORDER BY foo, baz.
Cũng xem phiên bản tốc ký rất gọn gàng nàycách tạo ra một chức năng so sánh như vậy một cách linh hoạt cho một số lượng phím tùy ý .

Sắp xếp vào một hướng dẫn, trật tự tĩnh

Nếu bạn muốn sắp xếp các thành phần vào một "thứ tự thủ công" như "foo", "bar", "baz" :

function cmp(array $a, array $b) {
    static $order = array('foo', 'bar', 'baz');
    return array_search($a['foo'], $order) - array_search($b['foo'], $order);
}

Đối với tất cả những điều trên, nếu bạn đang sử dụng PHP 5.3 trở lên (và bạn thực sự nên), hãy sử dụng các hàm ẩn danh cho mã ngắn hơn và để tránh có một hàm toàn cầu khác trôi nổi xung quanh:

usort($array, function (array $a, array $b) { return $a['baz'] - $b['baz']; });

Đó là cách đơn giản sắp xếp một mảng đa chiều phức tạp có thể. Một lần nữa, chỉ cần nghĩ về mặt giảng dạy PHP làm thế nào để biết mục nào trong hai mục là "lớn hơn" ; hãy để PHP thực hiện việc sắp xếp thực tế.

Ngoài ra, đối với tất cả những điều trên, để chuyển đổi giữa thứ tự tăng dần và giảm dần chỉ cần trao đổi $avà các $bđối số xung quanh. Ví dụ:

return $a['baz'] - $b['baz']; // ascending
return $b['baz'] - $a['baz']; // descending

Sắp xếp một mảng dựa trên mảng khác

Và sau đó là đặc thù array_multisort, cho phép bạn sắp xếp một mảng dựa trên một mảng khác:

$array1 = array( 4,   6,   1);
$array2 = array('a', 'b', 'c');

Kết quả dự kiến ​​ở đây sẽ là:

$array2 = array('c', 'a', 'b');  // the sorted order of $array1

Sử dụng array_multisortđể đạt được điều đó:

array_multisort($array1, $array2);

Kể từ phiên bản PHP 5.5.0, bạn có thể sử dụng array_columnđể trích xuất một cột từ một mảng đa chiều và sắp xếp mảng trên cột đó:

array_multisort(array_column($array, 'foo'), SORT_DESC, $array);

Kể từ phiên bản PHP 7.0.0, bạn cũng có thể trích xuất các thuộc tính từ một mảng các đối tượng.


Nếu bạn có nhiều trường hợp phổ biến hơn, vui lòng chỉnh sửa câu trả lời này.

146 hữu ích 5 bình luận chia sẻ