Heim > Fragen und Antworten > Hauptteil
Diese Frage ist als Referenz zu Problemen bei der Array-Sortierung in PHP gedacht. Es ist leicht zu glauben, dass Ihr spezieller Fall einzigartig ist und eine neue Frage verdient, aber die meisten davon sind tatsächlich nur geringfügige Variationen einer der Lösungen auf dieser Seite.
Wenn Ihre Frage als Duplikat dieser Frage geschlossen wurde, bitten Sie bitte nur dann um erneutes Öffnen Ihrer Frage, wenn Sie erklären können, warum sie sich erheblich von allen folgenden Fragen unterscheidet.
Wie sortiere ich ein Array in PHP?
Wie sortiere ich ein komplexesArray in PHP?
Wie sortiere ich ein Array von Objekten in PHP?
Grundlegendes eindimensionales Array; Mehrdimensionale Arrays, inkl. Array von Objekten enthält. Sortieren Sie ein Array basierend auf einem anderen Array
Verwenden Sie die SPL-Sortierung
Stabile Sortierung
Eine praktische Antwort unter Verwendung der vorhandenen PHP-Funktionen finden Sie unter 1. Eine wissenschaftlich detaillierte Antwort zu Sortieralgorithmen (die PHP-Funktionen implementieren und die Sie möglicherweise in sehr, sehr komplexen Fällen benötigen) finden Sie unter 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 开始,您还可以从对象数组中提取属性。