[英]PHP - Changing character sort order so e.g. “a” > “{” = True
I'm trying to customise PHP's usort
function to change the character sort order. 我正在尝试自定义PHP的usort
函数来更改字符排序顺序。
At present, only the " *
" symbol character equates to having a value less than letter characters, eg " a
", ie "*" < "a" = TRUE
. 目前,只有“ *
”符号字符等于具有小于字母字符的值,例如“ a
”,即"*" < "a" = TRUE
。 Other symbols, such as " {
", have values greater than letters, eg " a
", ie "{" < "a" = FALSE
. 其他符号,例如“ {
”,具有大于字母的值,例如“ a
”,即"{" < "a" = FALSE
。
I would like to sort so the value " {*}
" is at the top of the sorted array, as if the value was " *
". 我想排序所以值“ {*}
”位于排序数组的顶部,就像值是“ *
”一样。 Here's the function I'm currently using, to sort an array of objects by multiple properties of the objects. 这是我目前正在使用的函数,用于按对象的多个属性对对象数组进行排序。 [Attribution: It's a modified version of Will Shaver's code on the usort
docs .] [归因:这是Will Shaver在usort
文档上的代码的修改版本。]
function osort($array, $properties) {
//Cast to an array and specify ascending order for the sort if the properties aren't already
if (!is_array($properties)) $properties = [$properties => true];
//Run the usort, using an anonymous function / closures
usort($array, function($a, $b) use ($properties) {
//Loop through each specified object property to sort by
foreach ($properties as $property => $ascending) {
//If they are the same, continue to the next property
if ($a -> $property != $b -> $property) {
//Ascending order search for match
if ($ascending) {
//if a's property is greater than b, return 1, otherwise -1
return $a -> $property > $b -> $property ? 1 : -1;
}
//Descending order search for match
else {
//if b's property is greater than a's, return 1, otherwise -1
return $b -> $property > $a -> $property ? 1 : -1;
}
}
}
//Default return value (no match found)
return -1;
});
//Return the sorted array
return $array;
}
What about a usort
that prioritizes some characters in the order you define, and subsequently uses regular strcmp
? 关于什么usort
即在优先级定义级的一些人物,然后使用常规strcmp
?
Something like this: 像这样的东西:
<?php
$list = [ 'abc',
'{a}',
'*',
'{*}',
'{abc',
'}a',
]; // An array of strings to sort
$customOrderPrioritized = ['{','*','}']; // Add any characters here to prioritize them, in the order they appear in this array
function ustrcmp($a, $b, $customOrderPrioritized) {
if ($a === $b) return -1; // same, doesn't matter who goes first
$n = min(strlen($a), strlen($b)); // compare up to the length of the shortest string
for ($i = 0; $i < $n; $i++) {
if ($a[$i] === $b[$i]) continue; // matching character, continue to compare next
$a_prio = in_array($a[$i], $customOrderPrioritized);
$b_prio = in_array($b[$i], $customOrderPrioritized);
// If either one has a prioritized char...
if ($a_prio || $b_prio) {
if ($a_prio && $b_prio) {
// Both are prioritized, check which one is first...
return array_search($a[$i], $customOrderPrioritized) <= array_search($b[$i], $customOrderPrioritized) ? -1 : 1;
} elseif ($a_prio) {
return -1; // a < b
} else { // must be $b_prio
return +1; // b > a
}
}
return strcmp($a[i], $b[$i]); // compare single character
}
// if they have identical beginning, shortest should be first
return strlen($a) <= strlen($b) ? -1 : +1;
}
usort(
$list,
function($a, $b) use ($customOrderPrioritized){
return ustrcmp($a, $b, $customOrderPrioritized);
}
); // run custom comparison function, pass in $customOrderPrioritized (or make it global)
print_r($list); // print the list
/* The sorted array should look like:
Array
(
[0] => {*}
[1] => {a}
[2] => {abc
[3] => *
[4] => }a
[5] => abc
)
*/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.