這個問題旨在作為 PHP 中數組排序問題的參考。人們很容易認為您的特定案例是獨特的並且值得提出新問題,但大多數實際上只是此頁面上的解決方案之一的微小變化。
如果您的問題因與此問題重複而關閉,請僅在您能解釋為什麼它與以下所有問題顯著不同的情況下才要求重新打開您的問題。
如何在 PHP 中對陣列進行排序?
如何在 PHP 中對複雜陣列進行排序?
如何在 PHP 中對物件數組進行排序?
基本一維數組;包括。多維數組,包括。物件數組;包括。根據另一個數組對一個數組進行排序
使用 SPL 排序
穩定排序
有關使用PHP 現有函數的實際答案,請參閱1.,有關排序演算法的學術詳細答案(PHP 函數實現的以及您可能在非常非常複雜的情況下需要的),參見2。
P粉4764755512023-10-18 13:03:18
好吧,deceze已經涵蓋了大多數基本方法,我會嘗試看看其他類型的排序
SplHeap
class SimpleHeapSort extends SplHeap { public function compare($a, $b) { return strcmp($a, $b); } } // Let's populate our heap here (data of 2009) $heap = new SimpleHeapSort(); $heap->insert("a"); $heap->insert("b"); $heap->insert("c"); echo implode(PHP_EOL, iterator_to_array($heap));
輸出
c b a
SplMaxHeap
SplMaxHeap 類別提供堆的主要功能,將最大值保留在頂部。
$heap = new SplMaxHeap(); $heap->insert(1); $heap->insert(2); $heap->insert(3);
SplMinHeap
$heap = new SplMinHeap (); $heap->insert(3); $heap->insert(1); $heap->insert(2);
function bubbleSort(array $array) { $array_size = count($array); for($i = 0; $i < $array_size; $i ++) { for($j = 0; $j < $array_size; $j ++) { if ($array[$i] < $array[$j]) { $tem = $array[$i]; $array[$i] = $array[$j]; $array[$j] = $tem; } } } return $array; }
function selectionSort(array $array) { $length = count($array); for($i = 0; $i < $length; $i ++) { $min = $i; for($j = $i + 1; $j < $length; $j ++) { if ($array[$j] < $array[$min]) { $min = $j; } } $tmp = $array[$min]; $array[$min] = $array[$i]; $array[$i] = $tmp; } return $array; }
function insertionSort(array $array) { $count = count($array); for($i = 1; $i < $count; $i ++) { $j = $i - 1; // second element of the array $element = $array[$i]; while ( $j >= 0 && $array[$j] > $element ) { $array[$j + 1] = $array[$j]; $array[$j] = $element; $j = $j - 1; } } return $array; }
function shellSort(array $array) { $gaps = array( 1, 2, 3, 4, 6 ); $gap = array_pop($gaps); $length = count($array); while ( $gap > 0 ) { for($i = $gap; $i < $length; $i ++) { $tmp = $array[$i]; $j = $i; while ( $j >= $gap && $array[$j - $gap] > $tmp ) { $array[$j] = $array[$j - $gap]; $j -= $gap; } $array[$j] = $tmp; } $gap = array_pop($gaps); } return $array; }
function combSort(array $array) { $gap = count($array); $swap = true; while ( $gap > 1 || $swap ) { if ($gap > 1) $gap /= 1.25; $swap = false; $i = 0; while ( $i + $gap < count($array) ) { if ($array[$i] > $array[$i + $gap]) { // swapping the elements. list($array[$i], $array[$i + $gap]) = array( $array[$i + $gap], $array[$i] ); $swap = true; } $i ++; } } return $array; }
function mergeSort(array $array) { if (count($array) <= 1) return $array; $left = mergeSort(array_splice($array, floor(count($array) / 2))); $right = mergeSort($array); $result = array(); while ( count($left) > 0 && count($right) > 0 ) { if ($left[0] <= $right[0]) { array_push($result, array_shift($left)); } else { array_push($result, array_shift($right)); } } while ( count($left) > 0 ) array_push($result, array_shift($left)); while ( count($right) > 0 ) array_push($result, array_shift($right)); return $result; }
function quickSort(array $array) { if (count($array) == 0) { return $array; } $pivot = $array[0]; $left = $right = array(); for($i = 1; $i < count($array); $i ++) { if ($array[$i] < $pivot) { $left[] = $array[$i]; } else { $right[] = $array[$i]; } } return array_merge(quickSort($left), array( $pivot ), quickSort($right)); }
function permutationSort($items, $perms = array()) { if (empty($items)) { if (inOrder($perms)) { return $perms; } } else { for($i = count($items) - 1; $i >= 0; -- $i) { $newitems = $items; $newperms = $perms; list($foo) = array_splice($newitems, $i, 1); array_unshift($newperms, $foo); $res = permutationSort($newitems, $newperms); if ($res) { return $res; } } } } function inOrder($array) { for($i = 0; $i < count($array); $i ++) { if (isset($array[$i + 1])) { if ($array[$i] > $array[$i + 1]) { return False; } } } return True; }
// Radix Sort for 0 to 256 function radixSort($array) { $n = count($array); $partition = array(); for($slot = 0; $slot < 256; ++ $slot) { $partition[] = array(); } for($i = 0; $i < $n; ++ $i) { $partition[$array[$i]->age & 0xFF][] = &$array[$i]; } $i = 0; for($slot = 0; $slot < 256; ++ $slot) { for($j = 0, $n = count($partition[$slot]); $j < $n; ++ $j) { $array[$i ++] = &$partition[$slot][$j]; } } return $array; }
P粉9523651432023-10-18 09:01:08
$array = array(3, 5, 2, 8);
適用的排序函數:
排序
排序
分類
排序
natsort
#natcasesort
#ksort
#krsort
#它們之間的差異僅僅在於是否保留鍵值關聯(“a
”函數),是否按從低到高排序或反向排序(“r
” >” ),是否對值或鍵進行排序(“k
”)以及如何比較值(“nat
”與正常)。請參閱http://php.net /manual/en/array.sorting.php 取得概述和更多詳細資訊的連結。
$array = array( array('foo' => 'bar', 'baz' => 42), array('foo' => ..., 'baz' => ...), ... );
如果您想按每個項目的鍵「foo」對$array
進行排序,則需要一個自訂比較函數。上面的 sort
和相關函數適用於它們知道如何比較和排序的簡單值。 PHP 並不簡單地「知道」如何處理像 array('foo' => 'bar', 'baz' => 42) 這樣的複雜值;所以你需要告訴它。
為此,您需要建立一個比較函數。函數接受兩個元素,如果認為這些元素相等,則必須傳回0
;如果第一個值較低,則必須傳回低於0
的值;如果認為第一個值低於0,則必須傳回高於
0 的值
如果第一個值較高。這就是所需要的:
function cmp(array $a, array $b) { if ($a['foo'] < $b['foo']) { return -1; } else if ($a['foo'] > $b['foo']) { return 1; } else { return 0; } }
通常,您需要使用匿名函數作為回呼。如果您想使用方法或靜態方法,請參閱指定回呼的其他方法在 PHP 中。
然後您可以使用以下函數之一:
同樣,它們的差異僅在於是否保留鍵值關聯以及是否按值或鍵排序。請閱讀他們的文檔以了解詳細資訊。
使用範例:
usort($array, 'cmp');
usort
將從陣列中取出兩個項目並用它們呼叫您的 cmp
函數。因此cmp()
將以$a
的形式呼叫array('foo' => 'bar', 'baz' => 42)
和 $b
作為另一個array('foo' => ..., 'baz' => ...)
。然後函數會回到 usort
哪個值較大或它們是否相等。 usort
重複此過程,為 $a
和 $b
傳遞不同的值,直到陣列排序完畢。 cmp
函數將會被呼叫多次,至少與$array
中的值一樣多,且值的不同組合每次程式碼>$a和$b
。
要習慣這個想法,請嘗試以下操作:
function cmp($a, $b) { echo 'cmp called with $a:', PHP_EOL; var_dump($a); echo 'and $b:', PHP_EOL; var_dump($b); }
您所做的只是定義一種自訂方式來比較兩個項目,這就是您所需要的。這適用於各種值。
順便說一句,這適用於任何值,這些值不必是複雜的陣列。如果您想要進行自訂比較,也可以對簡單的數字陣列進行比較。
sort
按引用排序,不會傳回任何有用的內容! 請注意,陣列就地排序,您不需要將回傳值指派給任何內容。 $array = sort($array)
會將陣列替換為 true
,而不是排序後的陣列。只需 sort($array);
即可。
如果您想按數字鍵 baz
排序,您需要做的就是:
function cmp(array $a, array $b) { return $a['baz'] - $b['baz']; }
感謝數學的力量,這將傳回一個值< 0、0 或 > 0,取決於$a
是否小於、等於或大於$b
.
請注意,這對於 float
值不起作用,因為它們會被簡化為 int
並失去精確度。請改用明確 -1
、0
和 1
傳回值。
如果你有一個物件數組,它的工作方式是相同的:
function cmp($a, $b) { return $a->baz - $b->baz; }
您可以在比較函數中執行任何您需要的操作,包括呼叫函數:
function cmp(array $a, array $b) { return someFunction($a['baz']) - someFunction($b['baz']); }
第一個字串比較版本的捷徑:
function cmp(array $a, array $b) { return strcmp($a['foo'], $b['foo']); }
strcmp
完全符合cmp
的預期,它回傳-1
、0
或 1
.
PHP 7 引入了太空船運算子,它統一並簡化了跨類型的等於/小於/大於比較: p>
function cmp(array $a, array $b) { return $a['foo'] <=> $b['foo']; }
如果您想要主要按 foo
排序,但如果兩個元素的 foo
相等,則按 baz
排序:
function cmp(array $a, array $b) { if (($cmp = strcmp($a['foo'], $b['foo'])) !== 0) { return $cmp; } else { return $a['baz'] - $b['baz']; } }
對於熟悉的人來說,這相當於使用 ORDER BY foo, baz
的 SQL 查詢。
另請參閱這個非常簡潔的速記版本和如何為任意數量的鍵動態建立這樣的比較函數。
如果您想將元素排序為“手動順序”,例如“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); }
對於上述所有內容,如果您使用 PHP 5.3 或更高版本(並且您確實應該這樣做),請使用匿名函數來縮短程式碼並避免另一個全域函數:
usort($array, function (array $a, array $b) { return $a['baz'] - $b['baz']; });
這就是對複雜的多維數組進行排序的簡單方法。再次強調一下,教 PHP 如何判斷兩項中哪一項「更大」;讓 PHP 進行實際排序。
此外,對於上述所有內容,要在升序和降序之間切換,只需交換 $a
和 $b
參數即可。例如:
return $a['baz'] - $b['baz']; // ascending return $b['baz'] - $a['baz']; // descending
#還有一個奇特的 array_multisort
,它可以讓你依照下列條件對一個陣列進行排序:另一個:
$array1 = array( 4, 6, 1); $array2 = array('a', 'b', 'c');
這裡的預期結果是:
$array2 = array('c', 'a', 'b'); // the sorted order of $array1
使用array_multisort
到達那裡:
array_multisort($array1, $array2);
從 PHP 5.5.0 開始,您可以使用 array_column
從多維數組中提取列,並在該列上對數組進行排序:
array_multisort(array_column($array, 'foo'), SORT_DESC, $array);
您也可以任一方向對多個列進行排序:
array_multisort(array_column($array, 'foo'), SORT_DESC, array_column($array, 'bar'), SORT_ASC, $array);
從 PHP 7.0.0 開始,您也可以從物件陣列中提取屬性。