这个问题旨在作为PHP中关于数组排序的问题的参考。很容易认为您的特定情况是独特的,值得提出一个新问题,但大多数情况实际上是本页上某个解决方案的微小变化。 如果你的问题是这个问题的副本,请要求重新打开你的问题,只有当你能解释为什么它与下面所有的问题都有显著不同时。

我如何排序一个数组在PHP? 我如何排序一个复杂的数组在PHP? 如何在PHP中排序对象数组?


基本一维数组;包括多维数组,包括对象数组;包括根据一个数组对另一个数组排序 用SPL排序 稳定的排序

使用PHP现有函数的实际答案见1。,关于排序算法的学术详细答案(PHP函数实现,在非常非常复杂的情况下可能需要它),请参见2。


当前回答

最简单的方法是使用usort函数对数组进行排序,而不需要任何循环: 下面是一个例子:

   $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;
    });

其他回答

如果你想根据多个标准的绝对最大值对数组进行排序,这里有一个简单的方法:

usort($arr, function($item, $nextItem) {
    return (max($nextItem->firstNumber, $nextItem->secondNumber)) - (max($item->firstNumber, $item->secondNumber));
});

例子:

$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',
  ),
)

在PHP 5.3的闭包中,也可以使用闭包来确定排序的顺序。

例如,假设$array是一个包含month属性的对象数组。

 $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);
 }); 

稳定的排序

假设你有一个这样的数组:

['Kale', 'Kaleidoscope', 'Aardvark', 'Apple', 'Leicester', 'Lovely']

现在你只想对第一个字母排序:

usort($array, function($a, $b) {
    return strcmp($a[0], $b[0]);
});

结果是:

['Apple', 'Aardvark', 'Kale', 'Kaleidoscope', 'Lovely', 'Leicester']

那种东西不稳定!

敏锐的观察者可能已经注意到,数组排序算法(快速排序)并没有产生稳定的结果,并且相同首字母的单词之间的原始顺序没有被保留。这种情况很简单,我们应该比较整个字符串,但是让我们假设您的用例更复杂,比如在不同的字段上连续进行两次排序,它们不应该相互抵消。

施瓦兹变换

Schwartzian变换,也称为装饰-排序-不装饰习语,它使用固有的不稳定排序算法来实现稳定排序。

首先,你用另一个数组装饰每个数组元素,这个数组包含一个主键(value)和一个辅助键(它的索引或位置):

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]);
}));

瞧!您的原始比较代码回来了。

如果有人想要一个更简单的解决方案来操作数组,只需使用Laravel Collection包,它有一个实现的sortBy函数,可以让你简单地按键排序。

$collection->sortBy('forename')->sortBy('surname');

也就是说,为了先按a,然后按b,然后按c排序,正确的子句应该是

sortBy('c')->sortBy('b')->sortBy('a')

https://packagist.org/packages/tightenco/collect

如果你想按键值排序,那么你可以做一行,优雅而清晰。这将按价格递增来排序。使用array_multisort和array_column。

   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 ) )