How can I sort arrays and data in PHP?
This question is intended as a reference for questions about sorting arrays in PHP. It is easy to think that your particular case is unique, and worthy of a new question, but most are actually minor variations of one of the solutions on this page.
If your question is closed as a duplicate of this one, please ask for your question to be reopened only if you can explain why it differs markedly from all of the below.
如何在PHP中对数组进行排序?如何在PHP中对复杂数组进行排序?如何在PHP中对对象数组进行排序?
基本一维数组;包括多维数组,包括对象数组;包括基于另一个数组对一个数组进行排序
用SPL排序
稳定排序
有关使用PHP现有函数的实际答案,请参阅1。有关排序算法(PHP函数实现的以及您可能需要的真正、真正复杂的情况)的学术详细答案,请参阅2。
基本一维阵列
1 |
适用的排序功能:好的。
sort rsort asort arsort natsort natcasesort ksort krsort
这两者之间的区别仅仅在于是否保留了关键值关联("
如果要按每个条目的"foo"键对
为此,需要创建一个比较函数。该函数接受两个元素,如果这些元素被认为相等,则必须返回
1 2 3 4 5 6 7 8 9 |
通常,您会希望使用匿名函数作为回调函数。如果要使用方法或静态方法,请参阅在PHP中指定回调的其他方法。好的。
然后使用以下函数之一:好的。
usort uasort uksort
同样,它们只在保留键值关联和按值或键排序方面有所不同。阅读他们的文档了解详细信息。好的。
示例用法:好的。
1 |
要习惯这个想法,请尝试以下方法:好的。
1 2 3 4 5 6 |
你所做的就是定义一个自定义的方法来比较两个项目,这就是你所需要的。这适用于各种价值观。好的。
顺便说一下,这对任何值都有效,这些值不必是复杂的数组。如果您想进行自定义比较,也可以在一个简单的数字数组上进行比较。好的。
请注意,数组进行了适当的排序,您不需要将返回值赋给任何东西。
如果您想按
由于数学的强大,根据
请注意,对于
如果您有一个对象数组,它的工作方式相同:好的。
1 2 3 | function cmp($a, $b) { return $a->baz - $b->baz; } |
功能
您可以在比较函数内执行任何需要的操作,包括调用函数:好的。
串
第一个字符串比较版本的快捷方式:好的。
php 7引入了spaceship操作符,它统一并简化了不同类型的相等/较小/大于比较:好的。
按多个字段排序
如果主要按
1 2 3 4 5 6 7 |
对于熟悉的人,这相当于使用
如果要按"foo"、"bar"、"baz"等"手动顺序"对元素进行排序:好的。
1 2 3 4 | 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或更高版本(并且您确实应该这样做),请使用匿名函数来缩短代码,并避免使用其他全局函数:好的。
这就是对复杂的多维数组进行排序的简单程度。同样,只要从教PHP的角度来考虑如何分辨两个项目中哪个是"大的";让PHP来做实际的排序。好的。
同样,对于上述所有情况,要在升序和降序之间切换,只需交换
1 2 | return $a['baz'] - $b['baz']; // ascending return $b['baz'] - $a['baz']; // descending |
基于另一个数组对一个数组排序
还有一个特殊的
这里的预期结果是:好的。
1 |
用
1 |
从php 5.5.0开始,可以使用
1 |
从php 7.0.0开始,还可以从对象数组中提取属性。好的。
If you have more common cases, feel free to edit this answer.
Ok.
好啊。
好吧,大多数基本的方法已经被deceze所涵盖了,我试着看看其他类型的方法。
用SPL排序1 2 3 4 5 6 7 8 9 10 11 12 13 | 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)); |
产量
1 2 3 | c b a |
splmaxheap类提供堆的主要功能,使最大值保持在顶部。
1 2 3 4 | $heap = new SplMaxHeap(); $heap->insert(1); $heap->insert(2); $heap->insert(3); |
The SplMinHeap class provides the main functionalities of a heap, keeping the minimum on the top.
1 2 3 4 | $heap = new SplMinHeap (); $heap->insert(3); $heap->insert(1); $heap->insert(2); |
其他种类冒泡排序
来自维基百科关于气泡排序的文章:
Bubble sort, sometimes incorrectly referred to as sinking sort, is a simple sorting algorithm that works by repeatedly stepping through the list to be sorted, comparing each pair of adjacent items and swapping them if they are in the wrong order. The pass through the list is repeated until no swaps are needed, which indicates that the list is sorted. The algorithm gets its name from the way smaller elements"bubble" to the top of the list. Because it only uses comparisons to operate on elements, it is a comparison sort. Although the algorithm is simple, most of the other sorting algorithms are more efficient for large lists.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
选择排序
从维基百科关于选择排序的文章:
In computer science, selection sort is a sorting algorithm, specifically an in-place comparison sort. It has O(n2) time complexity, making it inefficient on large lists, and generally performs worse than the similar insertion sort. Selection sort is noted for its simplicity, and it has performance advantages over more complicated algorithms in certain situations, particularly where auxiliary memory is limited.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
插入排序
从维基百科关于插入排序的文章:
Insertion sort is a simple sorting algorithm that builds the final sorted array (or list) one item at a time. It is much less efficient on large lists than more advanced algorithms such as quicksort, heapsort, or merge sort. However, insertion sort provides several advantages:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
希尔排序
摘自维基百科关于ShellSort的文章:
Shellsort, also known as Shell sort or Shell's method, is an in-place comparison sort. It generalizes an exchanging sort, such as insertion or bubble sort, by starting the comparison and exchange of elements with elements that are far apart before finishing with neighboring elements.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 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; } |
梳排序
从维基百科关于梳排序的文章:
Comb sort is a relatively simple sorting algorithm originally designed by Wlodzimierz Dobosiewicz in 1980. Later it was rediscovered by Stephen Lacey and Richard Box in 1991. Comb sort improves on bubble sort.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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; } |
归并排序
来自维基百科关于合并排序的文章:
In computer science, a merge sort (also commonly spelled mergesort) is an O(n log n) comparison-based sorting algorithm. Most implementations produce a stable sort, which means that the implementation preserves the input order of equal elements in the sorted output
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 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; } |
快速排序
来自维基百科关于快速排序的文章:
Quicksort, or partition-exchange sort, is a sorting algorithm developed by Tony Hoare that, on average, makes O(n log n) comparisons to sort n items. In the worst case, it makes O(n2) comparisons, though this behavior is rare.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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)); } |
排列排序
从维基百科关于排列排序的文章:
Permutation sort, which proceeds by generating the possible permutations of the input array/list until discovering the sorted one.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | 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; } |
基数排序
摘自维基百科关于基数排序的文章:
In computer science, radix sort is a non-comparative integer sorting algorithm that sorts data with integer keys by grouping keys by the individual digits which share the same significant position and value.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | // 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; } |
稳定排序
假设您有一个这样的数组:
1 | ['Kale', 'Kaleidoscope', 'Aardvark', 'Apple', 'Leicester', 'Lovely'] |
现在您只需要对第一个字母进行排序:
结果是:
1 | ['Apple', 'Aardvark', 'Kale', 'Kaleidoscope', 'Lovely', 'Leicester'] |
那种不稳定!
敏锐的观察者可能已经注意到数组排序算法(quicksort)没有产生稳定的结果,同样的第一个字母的单词之间的原始顺序也没有被保留。这个例子很简单,我们应该对整个字符串进行比较,但是让我们假设您的用例更复杂,比如在不同的字段上进行两个连续的排序,这些排序不应该相互抵消对方的工作。
施瓦兹变换
Schwartzian转换,也称为修饰排序未修饰习语,通过固有的不稳定排序算法实现稳定排序。
首先,用包含主键(值)和次键(索引或位置)的另一个数组装饰每个数组元素:
1 2 3 | array_walk($array, function(&$element, $index) { $element = array($element, $index); // decorate }); |
这会将数组转换为:
1 2 3 4 5 | [ ['Kale', 0], ['Kaleidoscope', 1], ['Aardvark', 2], ['Apple', 3], ['Leicester', 4], ['Lovely', 5] ] |
现在,我们调整比较步骤;再次比较第一个字母,但如果它们相同,则使用第二个键保留原始顺序:
1 2 3 4 5 6 7 8 9 10 11 |
之后,我们重新装饰:
1 2 3 |
最终结果:
1 | ['Aardvark', 'Apple', 'Kale', 'Kaleidoscope', 'Leicester', 'Lovely'] |
重用呢?
您必须重写比较函数才能使用转换后的数组元素;您可能不想编辑精细的比较函数,因此下面是比较函数的包装器:
1 2 3 4 5 6 7 8 9 10 | function stablecmp($fn) { return function($a, $b) use ($fn) { if (($tmp = call_user_func($fn, $a[0], $b[0])) != 0) { return $tmp; } else { return $a[1] - $b[1]; } }; } |
让我们用这个函数编写排序步骤:
哇!你的原始比较代码又回来了。
对于带有闭包的PHP5.3,也可以使用闭包来确定排序顺序。
例如,假设$array是包含month属性的对象数组。
1 2 3 4 5 | $orderArray = array("Jan","Feb","Mar","Apr","May","June","July","Aug","Sept","Oct","Nov","Dec"); usort($array, function($a, $b) use ($orderArray){ return array_search($a->month, $orderArray) - array_search($b->month, $orderArray); }); |
链接
In net,linq is used for exporting,which provides a much nice syntax over comparison functions,especially when objects need to be solved by multiple fields.Linq to PHP,包括Yalinqo Library*有若干港口。用它,可以在没有写入复合比较函数的情况下,以单线的方式输出阵列。
1 2 3 | $sortedByName = from($objects)->orderBy('$v->name'); $sortedByCount = from($objects)->orderBy('$v->count'); $sortedByCountAndName = from($objects)->orderBy('$v->count')->thenBy('$v->name'); |
Comparisons can be further customized by passing a callback as a second argument,for example:
ZZU1
这是一个短暂的手法如果需要,这些方法中的链条回归迭代,迭代可以通过添加
与相关方法相关的呼叫适当阵列函数(EDOCX1,4,EDOCX1,5),EDOCX1,6,EDOCX1,7)等。
LINQ含有SQL激励的许多方法:过滤、聚集、集合等。当对阵列和物体进行复杂的变换需要在数据库中不重复时,这是最好的处理方法。
**developed by me,see readme for more details and comparison with other linq ports
按键值计算的多维输出
1.Natural sort of a multimensional array by a key value and also keep the original order(do not shuffle the main keys):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | function multisortByKeyValue( $k, $arr ) { $ids = array(); $index = 1; foreach ( $arr as $key => $row ) { $ids[ $key ] = intval( $row[ $k ] ) . '-' . $index . '-' . $key; $index ++; } natsort( $ids ); $arr = array_merge( $ids, $arr ); return $arr; } |
测试案例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | $arr = array( 'id1' => array( 'label' => 'ID 1', 'priority' => 30, ), 'id2' => array( 'label' => 'ID 2', 'priority' => 70, ), 'id3' => array( 'label' => 'ID 3', 'priority' => 20, ), 'id4' => array( 'label' => 'ID 4', 'priority' => 30, ), ); $sorted = multisortByKeyValue( 'priority', $arr ); // $sorted equals to: /* array ( 'id3' => array ( 'label' => 'ID 3', 'priority' => 20, ), 'id1' => array ( 'label' => 'ID 1', 'priority' => 30, ), 'id4' => array ( 'label' => 'ID 4', 'priority' => 30, ), 'id2' => array ( 'label' => 'ID 2', 'priority' => 70, ), ) */ |
It is very convenient to sort arrays with sorted function from NSPL:
基本输出
1 2 3 4 5 | // Sort array $sorted = sorted([3, 1, 2]); // Sort array in descending order $sortedDesc = sorted([3, 1, 2], true); |
函数结果
1 2 3 4 5 6 7 8 9 10 11 12 13 | // Sort array by the result of a given function (order words by length) $sortedByLength = sorted(['bc', 'a', 'abc'], 'strlen'); $sortedByLengthDesc = sorted(['bc', 'a', 'abc'], true, 'strlen'); // Sort array by the result of user-defined function (order words by the 1st character) $sortedByTheFirstCharacter = sorted(['bc', 'a', 'abc'], function($v) { return $v[0]; }); // Which is the same as $sortedByTheFirstCharacter = sorted(['bc', 'a', 'abc'], itemGetter(0)); $sortedByTheFirstCharacterDesc = sorted(['bc', 'a', 'abc'], true, itemGetter(0)); // itemGetter(0) returns a function which takes an argument with access by index/key // and returns the value at index 0 |
输出多维阵列
1 2 3 4 5 6 7 8 9 10 11 | // Sort multidimensional array (sort list of users by their names) $users = [ array('name' => 'Robert', 'age' => 20), array('name' => 'Alex', 'age' => 30), array('name' => 'Jack', 'age' => 25), ]; $sortedByName = sorted($users, itemGetter('name')); $sortedByNameDesc = sorted($users, true, itemGetter('name')); // itemGetter('name') returns a function which takes an argument with access by index/key // and returns the value of the 'name' key |
对象输出阵列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | // Lets assume we have class User(name, age) with properties name and age // and public methods getName() and getAge() $users = [ new User('Robert', 20), new User('Alex', 30), new User('Jack', 25), ]; // Sort list of objects by property value (sort list of users by their name) $sortedByName = sorted($users, propertyGetter('name')); $sortedByNameDesc = sorted($users, true, propertyGetter('name')); // propertyGetter('name') returns a function which takes an object // and returns the value of its 'name' property // Sort list of objects by method result (sort list of users by their age) $sortedByAge = sorted($users, methodCaller('getAge')); $sortedByAgeDesc = sorted($users, true, methodCaller('getAge')); // methodCaller('getAge') returns a function which takes an object // and returns the result of its getAge() method |
比较函数
1 2 3 4 5 6 7 | // Sort with a comparison function (order words lexicographically with strcmp) $sortedLexicographically = sorted(['bc', 'a', 'abc'], false, null, 'strcmp'); // Sort with user-defined comparison function (order words by the 1st character) $sortedByTheFirstCharacter = sorted(['bc', 'a', 'abc'], false, null, function($v1, $v2) { return chr($v1[0]) - chr($v2[0]); }); |
你可以在这里看到这些例子。
There are several ways to sort an array.I will mention some methods for doing that task.fist of all,I will give an integer array which is called as$numbers'.
1 |
这是创建一个阵列的正常方式。假设,我想把这个阵列从上游命令中删除,这样,该方法可以使用。
1 2 3 4 5 6 7 8 9 |
Now consider the output of that,
MGX1〔0〕
您可以看到打印的号码阵列的类型。如果你想被命名的数字阵列下载命令,则该方法可用于这项任务。
1 2 3 4 5 6 7 8 9 |
考虑输出
MGX1〔1〕
现在阵列的种类在下游命令中。好吧,让我们考虑一个联想阵列。我将给出一个联想阵列(联想阵列意味着,一个每个索引都有独特的键值的阵列。)
1 |
So,now I want to take this array in order to compending order according their value.Asort()method can be used for that.
1 2 3 4 5 6 7 8 9 |
如果按价值下调次序,则可以使用方框()。假设你想根据他们的密钥值输出这个阵列。在这方面,Ksort()方法可以使用。
1 2 3 4 5 6 7 8 9 |
现在考虑输出。MGX1〔2〕
现在的阵列是根据其键值来确定的,如果你想按其键值来排出该阵列,则可以使用该方法。
1 2 3 4 5 6 7 8 9 |
现在联想阵列是根据它们的键值下调的一种类型,看看输出。MGX1〔3〕
这些是在PHP中输出一个阵列的方法,希望你能有个主意。谢谢!
The simplest is to use usort function to sort array without any looping:Below is an example:
1 |
This will sort in desending order:
1 2 3 |
This will sort in asending order:
1 2 3 |