简体   繁体   English

PHP多维数组按键排序与例外

[英]php multidimensional array sort by key with exceptions

I am trying to sort a multidimensional array by its keys with exceptions to the sort. 我正在尝试通过其键对多维数组进行排序,但排序例外。 I know that I can use array_multisort(array_column ... to sort by multiple columns but my issue is that my sort is more by type than it is by alphanumeric or numerical. 我知道我可以使用array_multisort(array_column ...对多列进行排序,但是我的问题是我的排序更多地是按类型而不是字母数字或数字。

An example of the multidimensional array that I am working with is below: 我正在使用的多维数组的示例如下:

[
 0 ['woid'=>17642-1,'schedule'=>'URGENT']
 1 ['woid'=>17643-1,'schedule'=>'ASAP']
 2 ['woid'=>17643-2,'schedule'=>'ASAP']
 3 ['woid'=>17644-1,'schedule'=>'JAN']
 4 ['woid'=>NC323-1,'schedule'=>'URGENT']
 5 ['woid'=>NC324-1,'schedule'=>'ASAP']
]

What I want is to have this sorted by key= woid starting with 'NC' at the top sorted ASC, then sort the remaining by key= schedule with the following order: 我想要的是按key = woid排序,并在顶部的ASC woid 'NC'开头,然后按以下顺序对key = schedule的其余部分进行排序:

URGENT
JAN
FEB
MAR
APR
MAY
JUN
JUL
AUG
SEP
OCT
NOV
DEC
ASAP

all while retaining an ASC sort on the key= woid 同时在key = woid上保留ASC排序

I understand this may be confusing. 我了解这可能会造成混淆。 Below is an example of the desired outcome with the array example above: 下面是上面的数组示例的预期结果示例:

[
 0 ['woid'=>NC323-1,'schedule'=>'URGENT']
 1 ['woid'=>NC324-1,'schedule'=>'ASAP']
 2 ['woid'=>17642-1,'schedule'=>'URGENT']
 3 ['woid'=>17644-1,'schedule'=>'JAN']
 4 ['woid'=>17643-1,'schedule'=>'ASAP']
 5 ['woid'=>17643-2,'schedule'=>'ASAP']
]

If more information is needed or a larger example I am more than happy to take the time and provide it. 如果需要更多信息或更多示例,我很高兴花时间提供信息。

You'll need to use usort for multiple sort criteria like this. 您需要将usort用于这样的多个排序条件。

For your usort comparison function, after you've figured out whether each woid starts with 'NC', you can compare the results of that check mathematically, then use the order from your custom sort array, and finally use strcmp to break ties. 对于您的usort比较函数,在弄清楚每个woid是否以'NC'开头之后,可以数学比较该检查的结果,然后使用自定义排序数组中的顺序,最后使用strcmp打破平局。

$order = ['URGENT','JAN','FEB','MAR','APR','MAY','JUN',
          'JUL','AUG','SEP','OCT','NOV','DEC','ASAP'];

$order = array_flip($order);

usort($array, function($a, $b)  use ($order) {
    $aNC = strpos($a['woid'], 'NC') === 0;
    $bNC = strpos($b['woid'], 'NC') === 0;
    return ($bNC - $aNC)
        ?: ($order[$a['schedule']] - $order[$b['schedule']])
        ?: strcmp($a['woid'], $b['woid']);
});

In the first comparison, $aNC and $bNC will be booleans, but will be converted to ints (0 or 1) for the subtraction. 在第一个比较中, $aNC$bNC将为布尔值,但将被转换为整数(0或1)以进行减法。 If that comparison returns 0 (meaning both or neither woid value starts with 'NC'), the second comparison will be evaluated. 如果该比较返回0(意味着两个或两个woid值都以“ NC”开头),则将评估第二个比较。

In the second comparison, the position of the two schedule values in the $order array is subtracted. 在第二个比较中,减去$order数组中两个schedule值的位置。 If that comparison returns 0, (meaning both schedule values are the same), the third comparison will be evaluated. 如果该比较返回0(表示两个schedule值相同),则将评估第三个比较。

In the third comparison, strcmp is used to return <0, 0, or >0 depending on the string comparison of the two woid values. 在第三个比较中,根据两个woid值的字符串比较,使用strcmp返回<0、0或> 0。

Working Demo at 3v4l.org 3v4l.org上的工作演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM