为了账号安全,请及时绑定邮箱和手机立即绑定

使用PHP的uasort排序时保留键顺序(稳定排序)

使用PHP的uasort排序时保留键顺序(稳定排序)

倚天杖 2019-11-04 09:49:42
这个问题实际上是从SO上的另一个问题得到启发的,我想对其进行扩展。在PHP中有一个关联数组可以对它的值进行排序,但是使用一个(或多个)PHP内置的排序函数,这些值等于保留原始键顺序的值吗?这是我用来测试可能的解决方案的脚本(尚未找到):<?phpheader('Content-type: text/plain');for($i=0;$i<10;$i++){    $arr['key-'.$i] = rand(1,5)*10;}uasort($arr, function($a, $b){    // sort condition may go here //    // Tried: return ($a == $b)?1:($a - $b); //    // Tried: return $a >= $b; //});print_r($arr);?>陷阱:由于键是按原始数组排序的,因此请不要试图建议按键进行任何排序以恢复到原始顺序。我将它们排序为示例,以便更直观地查看输出中的顺序。
查看完整描述

3 回答

?
Qyouu

TA贡献1786条经验 获得超11个赞

array_multisort派上用场,只需将有序范围用作第二个数组($order只是临时的,它用于按其原始顺序对第一个数组的等效项进行排序):

$a = [

  "key-0" => 5,

  "key-99" => 3,

  "key-2" => 3,

  "key-3" => 7

];


$order = range(1,count($a));

array_multisort($a, SORT_ASC, $order, SORT_ASC);


var_dump($a);

输出量


array(4) {

  ["key-99"]=>

  int(3)

  ["key-2"]=>

  int(3)

  ["key-0"]=>

  int(5)

  ["key-3"]=>

  int(7)

}

我使用带有未排序键的测试数据来证明它可以正常工作。尽管如此,这是测试脚本的输出:


Array

(

    [key-1] => 10

    [key-4] => 10

    [key-5] => 20

    [key-8] => 20

    [key-6] => 30

    [key-9] => 30

    [key-2] => 40

    [key-0] => 50

    [key-3] => 50

    [key-7] => 50

)

缺点

它仅适用于预定义的比较,不能使用自己的比较功能。可能的值(的第二个参数array_multisort())为:


排序类型标志:


SORT_ASC -升序排序。

SORT_DESC -递减排序。

SORT_REGULAR -通常比较商品(不要更改类型)

SORT_NUMERIC -数字比较项目

SORT_STRING -比较项目作为字符串

SORT_LOCALE_STRING-根据当前语言环境将项目作为字符串进行比较。它使用语言环境,可以使用 setlocale()

SORT_NATURAL -使用“自然顺序”将项目作为字符串进行比较 natsort()

SORT_FLAG_CASE-可以与SORT_STRING或组合(按位或)以SORT_NATURAL区分大小写的字符串


查看完整回答
反对 回复 2019-11-04
?
哈士奇WWW

TA贡献1799条经验 获得超6个赞

为了完整起见,您还应该查看Schwartzian变换:


// decorate step

$key = 0;

foreach ($arr as &$item) {

        $item = array($item, $key++); // add array index as secondary sort key

}


// sort step

asort($arr); // sort it


// undecorate step

foreach ($arr as &$item) {

    $item = $item[0]; // remove decoration from previous step

}

PHP的默认排序算法正常工作与阵列,因为这样:


array(1, 0) < array(2, 0); // true

array(1, 1) < array(1, 2); // true

如果你想使用自己的分类标准可以使用uasort(),以及:


// each parameter is an array with two elements

// [0] - the original item

// [1] - the array key

function mysort($a, $b)

{

    if ($a[0] != $b[0]) {

        return $a[0] < $b[0] ? -1 : 1;

    } else {

        // $a[0] == $b[0], sort on key

        return $a[1] < $b[1] ? -1 : 1; // ASC

    }

}


查看完整回答
反对 回复 2019-11-04
  • 3 回答
  • 0 关注
  • 930 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信