Hướng dẫn sort array object php

To sort on one column of values, a combination of array_column() and array_multisort() is one sensible way. Demo

array_multisort(array_column($array, 'count'), $array);

Or only call upon usort() with the spaceship operator to perform less iterating in this scenario. Demo

usort($array, fn($a, $b) => $a->count <=> $b->count);

Notice that although the count values are cast as string type values in the input array, both sorting functions will correctly sort the values numerically instead of alphabetizing them (erroneously putting 23420 before `420). This is a reliable default feature.

Even if you are variably declaring the column to sort on, both approaches allow the variable to be used without any addition techniques.

Multisort Demo with variable

$property = 'count';
array_multisort(array_column($array, $property), $array);

Usort Demo with variable

$property = 'count';
usort($array, fn($a, $b) => $a->$property <=> $b->$property);

Both native sorting functions modify by reference, so do not try to access the sorted array by their return value.

array_multisort()'s default sorting direction is ascending, so it is of no benefit to explicitly use the SORT_ASC between the two array parameters. If descending sorting is desired, write SORT_DESC between the two arrays (as the second parameter).

usort() will sort ascending when the custom function body puts $a data on the left side of the spaceship operator and $b data on the right side. For sorting in a descending direction, just write $b data on the left and $a data on the right.

Both approaches are capable of receiving multiple sorting rules, but because this question only asks to sort on a single column, that guidance is inappropriate here.

It will be less efficient to call a function (like strcmp()) on every iteration while sorting. This is no longer best practice. Neither is using a two-way comparison (like > or <) to return a boolean outcome. A three-way comparison is expected from usort().

For sorting data with multiple rules/columns/properties, this answer gives good guidance.

Vietnamese (Tiếng Việt) translation by Thai An (you can also view the original English article)

Việc lấy thông tin từ một mảng thông tin đã được sắp xếp luôn dễ dàng hơn, nếu không bạn phải tìm kiếm từng phần tử của mảng mỗi lần. Ví dụ: giả sử bạn đã lưu trữ điểm của các sinh viên khác nhau trong một lớp trong một array (mảng) hoặc table (bảng dữ liệu). Nếu dữ liệu không được sắp xếp theo điểm số thu được, thì bạn sẽ phải xem điểm của từng sinh viên trong lớp trước khi bạn có thể biết ai đạt được điểm cao nhất và thấp nhất. Nếu bảng dữ liệu đã được sắp xếp từ thấp đến cao dựa trên điểm số, thì chỉ cần nhìn vào điểm số của sinh viên đầu tiên bạn sẽ biết điểm thấp nhất.

Việc sắp xếp thực hiện rất nhiều nhiệm vụ, yêu cầu truy xuất hoặc lấy một tập hợp dữ liệu cụ thể rất dễ dàng và hiệu quả. Trong hướng dẫn này, chúng ta sẽ tìm hiểu cách sử dụng các hàm PHP dựng sẵn để sắp xếp các loại mảng khác nhau.

Sắp xếp một mảng theo giá trị

Sắp xếp một mảng theo giá trị của các phần tử của nó trong PHP rất dễ dàng. Bạn có thể chọn duy trì hoặc loại bỏ các liên kết key-value (khóa - giá trị) và bạn cũng có thể định nghĩa các hàm riêng của mình để xác định cách sắp xếp các phần tử. Tôi sẽ chỉ cho bạn làm sao trong phần này của hướng dẫn.

Bạn có thể sử dụng hàm sort(&$mảng, $sort_flags) để sắp xếp các giá trị của một mảng từ thấp đến cao. Tuy nhiên, nó sẽ không duy trì bất kỳ liên kết key-value nào khi sắp xếp mảng đó. Các key mới được gán cho các phần tử đã sắp xếp thay vì một sắp xếp lại đơn giản. Tham số tùy chọn thứ hai cho phép bạn chỉ định cách sắp xếp các thành phần. Tham số này có thể có sáu giá trị khác nhau:

  1. SORT_REGULAR - tham số này sẽ sắp xếp các giá trị mà không thay đổi kiểu của chúng.
  2. SORT_NUMERIC - tham số này sẽ sắp xếp các giá trị bằng cách so sánh chúng bằng số lượng.
  3. SORT_STRING - tham số này sẽ sắp xếp các giá trị bằng cách so sánh chúng theo dạng string (string).
  4. SORT_LOCALE_STRING - tham số này sẽ so sánh các giá trị dưới dạng string dựa trên miền địa phương hiện tại. Bạn có thể tự cập nhật miền địa phương bằng cách sử dụng setlocale().
  5. SORT_NATURAL - tham số này sẽ sắp xếp các phần tử bằng cách sử dụng "sắp xếp tự nhiên" trong khi so sánh chúng dưới dạng string.
  6. SORT_FLAG_CASE, tham số này có thể được kết hợp với SORT_STRING hoặc SORT_NATURAL để tắt phân biệt chữ hoa chữ thường trong khi sắp xếp string.

Dưới đây là một vài ví dụ sắp xếp để giúp bạn nhanh chóng nắm bắt sự khác biệt giữa tất cả các cờ sắp xếp.

Trong ví dụ, sắp xếp thông thường (regular sort), các chuỗi chữ số được chuyển đổi thành các giá trị số của chúng và việc sắp xếp được thực hiện phù hợp. Chuỗi "Apple" không phải là số nên không bị ảnh hưởng và được so sánh dưới dạng string.

Trong ví dụ thứ hai, sắp xếp các số (numeric sort), chúng tôi muốn dữ liệu được sắp xếp dựa trên giá trị số để "Apple" được chuyển đổi thành giá trị số 0 và xuất hiện đầu tiên. Phần còn lại của các giá trị được sắp xếp như mong đợi.

Trong ví dụ thứ ba, tất cả các giá trị được coi là string. Có nghĩa là thay vì so sánh giá trị số của 123 hoặc 3249832 với 38, chúng được so sánh như một string - mỗi lúc một ký tự. Vì "1" xuất hiện trước "3", giá trị 123 được coi là thấp hơn 38.

Nếu bạn muốn sắp xếp các giá trị mảng của mình từ cao đến thấp thay vì thấp đến cao, bạn có thể làm như vậy với sự trợ giúp của hàm rsort(). Nó chấp nhận tất cả các tham số giống như sort() nhưng sắp xếp các giá trị theo thứ tự ngược lại. Nó cũng không duy trì bất kỳ liên kết giá trị khóa nào, vì vậy nó không phải là một lựa chọn tốt để sắp xếp các mảng liên kết.

Sắp xếp một mảng liên kết

Liên kết giữa khóa và giá trị trở nên quan trọng khi bạn đang xử lý các mảng liên kết. Xem xét ví dụ sau đây, trong đó một mảng liên kết được sử dụng để lưu trữ tên của những người khác nhau và loại trái cây yêu thích của họ. Nếu bạn muốn sắp xếp danh sách theo thứ tự abc theo tên của các loại trái cây, thì việc sử dụng hàm sort() từ phần trước sẽ dẫn đến việc mất các khóa liên quan.

 "Orange", "John" => "Banana", "Patricia" => "Apple", "Jennifer" => "Mango", "Mary" => "Grapes"];

echo "Before Sorting — \n";
foreach($fruit_preferences as $person=>$preference) {
    echo $person." likes ".$preference."\n";
}

/*
Before Sorting — 
James likes Orange
John likes Banana
Patricia likes Apple
Jennifer likes Mango
Mary likes Grapes
*/

sort($fruit_preferences);

echo "After Sorting  — \n";
foreach($fruit_preferences as $person=>$preference) {
    echo $person." likes ".$preference."\n";
}

/*
After Sorting  — 
0 likes Apple
1 likes Banana
2 likes Grapes
3 likes Mango
4 likes Orange
*/

?>

Như bạn có thể thấy, chúng tôi không chỉ mất liên kết của mọi người với các loại trái cây yêu thích của họ, chúng tôi còn mất đi tên của những người khác nhau. Mỗi giá trị đã sắp xếp được chỉ định một chỉ số số mới dựa trên vị trí của nó trong mảng được sắp xếp.

Để giúp bạn giải quyết vấn đề này một cách dễ dàng, PHP có hai hàm khác nhau duy trì liên kết khóa - giá trị trong khi sắp xếp các mảng theo các giá trị của chúng. Hai hàm này là asort()arsort(). Đoạn code sau sắp xếp mảng tương tự $fruit_preferences nhưng sử dụng asort().

 "Orange", "John" => "Banana", "Patricia" => "Apple", "Jennifer" => "Mango", "Mary" => "Grapes"];

echo "Before Sorting — \n";
foreach($fruit_preferences as $person=>$preference) {
    echo $person." likes ".$preference."\n";
}

/*
Before Sorting — 
James likes Orange
John likes Banana
Patricia likes Apple
Jennifer likes Mango
Mary likes Grapes
*/

asort($fruit_preferences);

echo "After Sorting  — \n";
foreach($fruit_preferences as $person=>$preference) {
    echo $person." likes ".$preference."\n";
}

/*
After Sorting  — 
Patricia likes Apple
John likes Banana
Mary likes Grapes
Jennifer likes Mango
James likes Orange
*/

?>

Rõ ràng từ ví dụ trên, giá trị Apple chuyển lên đầu tiên trong khi vẫn duy trì mối liên hệ với Patricia. Tên trái cây có thể được sắp xếp ngược lại dễ dàng bằng cách sử dụng hàm arsort().

Cả hai hàm này đều chấp nhận các cờ sắp xếp giống nhau làm giá trị của tham số tùy chọn thứ hai của chúng là sort()rsort().

Sắp xếp các phần tử mảng theo giá trị với các hàm do người dùng định nghĩa

Bốn chức năng sắp xếp có thể dễ dàng xử lý các nhu cầu sắp xếp phổ biến của bạn với sự trợ giúp của các cờ khác nhau. Tuy nhiên, đôi khi tiêu chí của bạn để so sánh các yếu tố mảng có thể khác nhau.

Cho rẵng bạn có một loạt các từ ngẫu nhiên cần được sắp xếp theo thứ tự abc. Tuy nhiên, bạn cũng muốn sắp xếp chúng dựa trên chiều dài của chúng trước khi sắp xếp chúng theo thứ tự bảng chữ cái. Ví dụ, zoo sẽ nằm sau apple trong cách sắp xếp theo thứ tự chữ cái truyền thống. Tuy nhiên, nếu muốn hiển thị các từ ngắn trước những từ dài hơn, zoo sẽ xuất hiện trước apple. Trong cùng một tập hợp các chữ cái, ape sẽ nằm trước zoo theo thứ tự chữ cái.

Về cơ bản, ban đầu các từ được sắp xếp dựa trên độ dài của chúng và sau đó các từ có cùng số lượng chữ cái được sắp xếp theo thứ tự abc trong nhóm riêng của chúng. Kiểu sắp xếp này không được tích hợp vào PHP nên chúng ta sẽ phải tự viết hàm sắp xếp riêng.

Điều mà PHP làm trong trường hợp này là cung cấp cho bạn một vài hàm có thể được sử dụng để truyền vào mảng mà bạn muốn sắp xếp cùng với tên của hàm sắp xếp của riêng bạn.

Bạn có thể sử dụng hàm usort() để sắp xếp các giá trị mảng trong các mảng thông thường. Tương tự, bạn có thể sử dụng hàm uasort() để sắp xếp các giá trị trong các mảng liên kết trong khi vẫn duy trì các liên kết khóa - giá trị.

Đoạn code dưới đây cho thấy cách thực hiện hành vi này.

 strlen($word_b)) {
        return 1;
    }
}

usort($random_words, "custom_sort");
echo "\nCustom Sort Function: \n";
foreach($random_words as $element) {
    echo str_pad($element, 9)." ";
}

/*
Custom Sort Function: 
ape       eye       pie       zoo       apple     banana    picnic    elephant
*/

?>

Trong các hàm callback dùng để sắp xếp tùy chỉnh, chúng ta phải trả về một số nguyên nhỏ hơn 0 để cho thấy giá trị đầu tiên nhỏ hơn giá trị thứ hai. Trả về 0 nếu giá trị đầu tiên bằng giá trị thứ hai. Trả về một số nguyên lớn hơn 0 nếu giá trị đầu tiên lớn hơn giá trị thứ hai.

Vì tiêu chí sắp xếp chính của chúng tôi là độ dài của chuỗi, chúng tôi trực tiếp trả về -1 nếu từ đầu tiên ngắn hơn từ thứ hai. Tương tự, chúng tôi trực tiếp trả về 1 nếu từ đầu tiên dài hơn từ thứ hai. Nếu hai từ có độ dài bằng nhau, chúng ta so sánh chúng theo thứ tự bảng chữ cái bằng cách sử dụng hàm strcmp() và trả về giá trị của nó.

Như bạn có thể thấy trong kết quả, hàm sắp xếp tùy chỉnh của chúng tôi sắp xếp lại các từ chính xác theo cách chúng tôi muốn.

Sắp xếp một mảng theo khóa (key)

Sắp xếp một mảng dựa trên các khóa của nó thường hữu ích khi bạn đang xử lý các mảng liên kết. Chẳng hạn, bạn có thể có một mảng với thông tin về tổng số sân bay ở các quốc gia khác nhau. Giả sử rằng tên của các quốc gia khác nhau là khóa và số lượng sân bay là giá trị, bạn có thể muốn sắp xếp tên quốc gia theo thứ tự bảng chữ cái. Điều này rất dễ thực hiện với các hàm ksort()krsort(). Cả hai hàm này sẽ duy trì liên kết khóa - giá trị của các phần tử mảng sau khi sắp xếp. Hàm ksort() sắp xếp các phím từ thấp đến cao và krsort() sắp xếp các phím từ cao đến thấp.

Dưới đây là một ví dụ sắp xếp cơ bản:

 13513, "Brazil" => 4093, "Mexico" => 1714, "Canada" => 1467, "Russia" => 1218, "Argentina" => 1138, "Bolivia" => 855, "Colombia" => 836, "Paraguay" => 799, "Indonesia" => 673];

ksort($airport_count);

foreach($airport_count as $country=>$count) {
    echo str_pad($country, 15)." ".$count."\n";
}

/*
Argentina       1138
Bolivia         855
Brazil          4093
Canada          1467
Colombia        836
Indonesia       673
Mexico          1714
Paraguay        799
Russia          1218
United States   13513
*/

?>

Bạn cũng có thể không cần tự xây dựng hàm của riêng bạn để sắp xếp các khóa của mảng bằng hàm uksort(). Giống như hàm usort(), hàm callback trong uksort() cũng yêu cầu bạn trả về một số nguyên nhỏ hơn 0 nếu khóa thứ nhất nhỏ hơn khóa thứ hai và số nguyên lớn hơn 0 nếu khóa thứ nhất lớn hơn khóa thứ hai. Hàm này cũng duy trì liên kết khóa - giá trị của các phần tử trong mảng.

 13513, "Brazil" => 4093, "Mexico" => 1714, "Canada" => 1467, "Russia" => 1218, "Argentina" => 1138, "Bolivia" => 855, "Colombia" => 836, "Paraguay" => 799, "Indonesia" => 673];

function custom_sort($word_a, $word_b) {
    if (strlen($word_a) < strlen($word_b)) {
        return -1;
    }
    if (strlen($word_a) == strlen($word_b)) {
        return strcmp($word_a, $word_b);
    }
    if (strlen($word_a) > strlen($word_b)) {
        return 1;
    }
}

uksort($airport_count, "custom_sort");

foreach($airport_count as $country=>$count) {
    echo str_pad($country, 15)." ".$count."\n";
}

/*
Brazil          4093
Canada          1467
Mexico          1714
Russia          1218
Bolivia         855
Colombia        836
Paraguay        799
Argentina       1138
Indonesia       673
United States   13513
*/

?>

Trong ví dụ trên, chúng tôi đã sử dụng hàm sắp xếp tùy chỉnh của phần trước để sắp xếp tên của các quốc gia trước theo độ dài của tên và sau đó theo thứ tự bảng chữ cái.

Sắp xếp các mảng nhiều chiều trong PHP

Việc đảm nhận những thông tin đa chiều rõ ràng rất phổ biến trong đời thường. Chẳng hạn, các tổ chức sẽ lưu trữ điểm của tất cả sinh viên của nhiều môn học trong một bảng thay vì tạo các bảng mới cho mỗi môn. Nếu bạn phải lưu trữ thông tin tương tự trong PHP, bạn cũng muốn làm điều đó bằng cách sử dụng một mảng đa chiều thay vì mảng riêng cho từng đối tượng.

Trong hướng dẫn này, chúng ta sẽ tìm hiểu cách sắp xếp một mảng nhiều chiều bằng cách sử dụng danh sách các tòa nhà cao nhất thế giới làm ví dụ. Mảng của chúng tôi sẽ chứa thông tin về tên của tòa nhà, thành phố và quốc gia nơi nó tọa lạc, số tầng và tổng chiều cao tính bằng mét cùng với năm mà nó được xây dựng.

Khi bạn muốn sắp xếp các giá trị trong một mảng nhiều chiều dựa trên một field cụ thể, bạn chỉ cần sử dụng hàm usort(). Ví dụ dưới đây sẽ giúp bạn hiểu kỹ thuật này tốt hơn.

 "Burj Khalifa","City" => "Dubai","Country" => "United Arab Emirates","Height" => 828,"Floors" => 163,"Year" => 2010],
    ["Building" => "Shanghai Tower","City" => "Shanghai","Country" => "China","Height" => 632,"Floors" => 128,"Year" => 2015],
    ["Building" => "Abraj Al-Bait Towers","City" => "Mecca","Country" => "Saudi Arabia","Height" => 601,"Floors" => 120,"Year" => 2012],
    ["Building" => "Ping An Finance Center","City" => "Shenzhen","Country" => "China","Height" => 599,"Floors" => 115,"Year" => 2017],
    ["Building" => "Lotte World Tower","City" => "Seoul","Country" => "South Korea" ,"Height" => 554,"Floors" => 123,"Year" => 2016]
];

function storey_sort($building_a, $building_b) {
    return $building_a["Floors"] - $building_b["Floors"];
}

usort($tallest_buildings, "storey_sort");

foreach($tallest_buildings as $tall_building) {
    list($building, $city, $country, $height, $floors) = array_values($tall_building);
    echo $building." is in ".$city.", ".$country.". It is ".$height." meters tall with ".$floors." floors.\n";
}

/*
Ping An Finance Center is in Shenzhen, China. It is 599 meters tall with 115 floors.
Abraj Al-Bait Towers is in Mecca, Saudi Arabia. It is 601 meters tall with 120 floors.
Lotte World Tower is in Seoul, South Korea. It is 554 meters tall with 123 floors.
Shanghai Tower is in Shanghai, China. It is 632 meters tall with 128 floors.
Burj Khalifa is in Dubai, United Arab Emirates. It is 828 meters tall with 163 floors.
*/

?>

Trong ví dụ trên, thông tin về mỗi tòa nhà được lưu trữ trong mảng riêng của nó bên trong mảng chính $heightest_buildings. Hàm storey_sort() chỉ cần trừ số tầng trong tòa nhà thứ hai ra khỏi tòa nhà thứ nhất để xác định tòa nhà nào nhỏ hơn theo tiêu chí của chúng tôi. Chúng tôi không phải lo lắng về việc trả lại một giá trị âm hoặc dương cụ thể vì tất cả các giá trị âm có nghĩa là nhỏ hơn và tất cả các giá trị dương có nghĩa là lớn hơn.

Cuối cùng, chúng tôi chỉ lặp qua mảng chính và in ra thông tin về từng tòa nhà.

Tổng kết

Trong hướng dẫn này, tôi đã chỉ cho bạn một số hàm khác nhau trong PHP có thể được sử dụng để sắp xếp các mảng theo khóa hoặc giá trị của chúng. Chúng tôi cũng đã biết được cách sắp xếp một mảng theo các khóa hoặc giá trị của nó bằng các tiêu chí sắp xếp tùy chỉnh của riêng chúng tôi với sự trợ giúp của các hàm uksrot()uasort(). Phần cuối thảo luận cách sắp xếp tất cả các giá trị trong một mảng nhiều chiều chỉ bằng một field cụ thể.

Tôi hy vọng bạn đã học được điều mới mẻ qua hướng dẫn này. Nếu bạn có bất kỳ câu hỏi hoặc đề xuất nào, xin vui lòng cho tôi biết trong phần bình luận. Cách tốt nhất để học là thử và tạo ra một số ví dụ của riêng bạn, sắp xếp các mảng bằng cách sử dụng các hàm này.