如何在PHP中对数组和数据进行排序?
本问题旨在作为有关PHP中数组排序问题的参考。很容易认为您的特定案例是独特的,值得提出一个新问题,但大多数都是本页解决方案之一的微小变化 如果您的问题作为本问题的副本关闭,请要求重新打开您的问题,前提是您可以解释为什么它与以下所有问题明显不同 如何在PHP中对数组排序?如何在PHP中对数组和数据进行排序?,php,arrays,sorting,object,spl,Php,Arrays,Sorting,Object,Spl,本问题旨在作为有关PHP中数组排序问题的参考。很容易认为您的特定案例是独特的,值得提出一个新问题,但大多数都是本页解决方案之一的微小变化 如果您的问题作为本问题的副本关闭,请要求重新打开您的问题,前提是您可以解释为什么它与以下所有问题明显不同 如何在PHP中对数组排序? 如何在PHP中对复杂数组进行排序? 如何在PHP中对对象数组进行排序 有关使用PHP现有函数的实际答案,请参见1。有关排序算法的学术详细答案(PHP函数实现了哪些排序算法,对于非常非常复杂的情况,您可能需要哪些排序
如何在PHP中对复杂数组进行排序?
如何在PHP中对对象数组进行排序
function cmp(array $a, array $b) {
return someFunction($a['baz']) - someFunction($b['baz']);
}
排序
rsort
asort
arsort
natsort
natcasesort
ksort
krsort
$array
进行排序,则需要自定义比较函数。上述sort
和相关函数处理简单的值,它们知道如何比较和排序。PHP并不简单地“知道”如何处理复杂的值,比如array('foo'=>'bar','baz'=>42)
;所以你需要说出来
为此,您需要创建一个比较函数。该函数包含两个元素,如果认为这些元素相等,则必须返回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;
}
}
usort
将从数组中提取两项,并使用它们调用cmp
函数。因此,cmp()
将使用$a
作为数组('foo'=>'bar','baz'=>42)
调用,$b
作为另一个数组('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);
}
您所做的只是定义一种自定义方式来比较两个项目,这就是您所需要的。这适用于各种各样的价值观
顺便说一下,这适用于任何值,值不必是复杂的数组。如果您想进行自定义比较,也可以在一个简单的数字数组上进行
排序
按引用排序,不返回任何有用的内容!
请注意,数组排序到位,您不需要将返回值分配给任何对象$array=sort($array)
将用true
替换数组,而不是用排序数组。只需排序($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引入了,它统一并简化了不同类型之间的等/小/大比较:
function cmp(array $a, array $b) {
return $a['foo'] <=> $b['foo'];
}
对于熟悉的人来说,这相当于使用SQL查询orderbyfoo,baz
另请参见和
按手动、静态顺序排序
如果要将元素排序为“手动顺序”,如“foo”、“bar”、“baz”:
综上所述,如果您使用的是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
基于另一个数组对一个数组进行排序
还有一种特殊的方法,可以让你根据一个数组对另一个数组进行排序:
$array1 = array( 4, 6, 1);
$array2 = array('a', 'b', 'c');
这里的预期结果是:
$array2 = array('c', 'a', 'b'); // the sorted order of $array1
使用array\u multisort
到达:
array_multisort($array1, $array2);
从PHP 5.5.0开始,您可以使用array\u 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年起
$array2 = array('c', 'a', 'b'); // the sorted order of $array1
array_multisort($array1, $array2);
array_multisort(array_column($array, 'foo'), SORT_DESC, $array);
array_multisort(array_column($array, 'foo'), SORT_DESC,
array_column($array, 'bar'), SORT_ASC,
$array);
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
$heap = new SplMaxHeap();
$heap->insert(1);
$heap->insert(2);
$heap->insert(3);
$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;
}
['Kale', 'Kaleidoscope', 'Aardvark', 'Apple', 'Leicester', 'Lovely']
usort($array, function($a, $b) {
return strcmp($a[0], $b[0]);
});
['Apple', 'Aardvark', 'Kale', 'Kaleidoscope', 'Lovely', 'Leicester']
array_walk($array, function(&$element, $index) {
$element = array($element, $index); // decorate
});
[
['Kale', 0], ['Kaleidoscope', 1],
['Aardvark', 2], ['Apple', 3],
['Leicester', 4], ['Lovely', 5]
]
usort($array, function($a, $b) {
// $a[0] and $b[0] contain the primary sort key
// $a[1] and $b[1] contain the secondary sort key
$tmp = strcmp($a[0][0], $b[0][0]);
if ($tmp != 0) {
return $tmp; // use primary key comparison results
}
return $a[1] - $b[1]; // use secondary key
});
array_walk($array, function(&$element) {
$element = $element[0];
});
['Aardvark', 'Apple', 'Kale', 'Kaleidoscope', 'Leicester', 'Lovely']
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];
}
};
}
usort($array, stablecmp(function($a, $b) {
return strcmp($a[0], $b[0]);
}));
$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);
});
$sortedByName = from($objects)->orderBy('$v->name');
$sortedByCount = from($objects)->orderBy('$v->count');
$sortedByCountAndName = from($objects)->orderBy('$v->count')->thenBy('$v->name');
$sortedByFilenameNat = from($objects)->orderBy('$v->filename', 'strnatcmp');
// Sort array
$sorted = sorted([3, 1, 2]);
// Sort array in descending order
$sortedDesc = sorted([3, 1, 2], true);
// 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
// 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
// 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
// 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]);
});
$array_compare= array("0" =>4,"1"=>2,"2"=>500,"3"=>100);
usort($array_compare, function($a, $b) {
return ($b['x1'] - $a['x1']) > 0 ? 1 :-1;
});
usort($array_compare, function($a, $b) {
return ($b['x1'] - $a['x1']) < 0 ? 1 :-1;
});
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;
}
$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,
),
)
*/
$number = array(8,9,3,4,0,1,2);
<?php
$number = array(8,9,3,4,0,1,2);
sort($number);
foreach ($number as $value) {
echo $value." ";
}
?>
<?php
$number = array(8,9,3,4,0,1,2);
rsort($number);
foreach ($number as $value) {
echo $value." ";
}
?>
$number = array('eight'=>8,'nine'=>9,'three'=>3,'fore'=>4,'zero'=>0,'one'=>1,'two'=>2);
<?php
$number = array('eight'=>8,'nine'=>9,'three'=>3,'fore'=>4,'zero'=>0,'one'=>1,'two'=>2);
asort($number);
foreach ($number as $value) {
echo $value." ";
}
?>
<?php
$number = array('eight'=>8,'nine'=>9,'three'=>3,'fore'=>4,'zero'=>0,'one'=>1,'two'=>2);
ksort($number);
foreach ($number as $value) {
echo $value." ";
}
?>
<?php
$number = array('eight'=>8,'nine'=>9,'three'=>3,'fore'=>4,'zero'=>0,'one'=>1,'two'=>2);
krsort($number);
foreach ($number as $value) {
echo $value." ";
}
?>
Array([0] => Array ( [name] => eggs [price] => 1 ) [1] => Array ( [name] => coffee [price] => 9.99 ) [2] => Array ( [name] => rice [price] => 4.04 ) )
array_multisort (array_column($array, 'price'), SORT_ASC, $array);
Array ( [0] => Array ( [name] => eggs [price] => 1 ) [1] => Array ( [name] => rice [price] => 4.04 ) [2] => Array ( [name] => coffee [price] => 9.99 ) )
$multidimArray = [
'a' => [
'boolean' => true,
'natString' => 'text10',
'object' => (object)['prop' => 2],
'float' => -.5,
'mixed' => []
],
'b' => [
'boolean' => true,
'natString' => 'text12',
'object' => (object)['prop' => 4],
'float' => 0,
'mixed' => null
],
'c' => [
'boolean' => false,
'natString' => 'text100',
'object' => (object)['prop' => 9],
'float' => -.5,
'mixed' => false
],
'd' => [
'boolean' => true,
'natString' => 'text1',
'object' => (object)['prop' => 9],
'float' => -5,
'mixed' => "\0"
],
'e' => [
'boolean' => false,
'natString' => 'text2',
'object' => (object)['prop' => 2],
'float' => .5,
'mixed' => ''
]
];
uasort($multidimArray, function($a, $b) {
return [$b['boolean'], $a['float']] <=> [$a['boolean'], $b['float']];
});
uasort($multidimArray, function($a, $b) {
return [$a['mixed'], $a['object']->prop, $a['boolean']] <=> [$b['mixed'], $b['object']->prop, $b['boolean']];
});
uasort($multidimArray, function($a, $b) {
return [count(get_object_vars($a['object'])), is_iterable($a['mixed']), strlen($a['natString']), $a['natString']]
<=>
[count(get_object_vars($b['object'])), is_iterable($b['mixed']), strlen($b['natString']), $b['natString']];
});
$collection->sortBy('forename')->sortBy('surname');
sortBy('c')->sortBy('b')->sortBy('a')
$foo = new stdClass;
$foo->createdDate = '10';
$foo->uploadedDate = '5';
$bar = new stdClass;
$bar->createdDate = '1';
$bar->uploadedDate = '12';
$baz = new stdClass;
$baz->createdDate = '25';
$baz->uploadedDate = '0';
$arr = [$foo, $bar, $baz];
// Order array by the highest number between "createdDate" and "uploadedDate".
usort($arr, function($item, $nextItem) {
return (max($nextItem->createdDate, $nextItem->uploadedDate)) - (max($item->createdDate, $item->uploadedDate));
});
array (
0 =>
(object) array(
'createdDate' => '25',
'uploadedDate' => '0',
),
1 =>
(object) array(
'createdDate' => '1',
'uploadedDate' => '12',
),
2 =>
(object) array(
'createdDate' => '10',
'uploadedDate' => '5',
),
)