我有数组并包含 50 个值,
示例
[
'london',
'bluehit',
'green',
'lonpark',
'abc',
'aab',
'lonsee',
]
我想优先对以提供的字符串开头的值进行排序,然后按传统的字母顺序排序。
如果我给出一个参数为
lon
那么我的数组应该排序为:
[
'london',
'lonpark',
'lonsee',
'aab',
'abc',
'blurhit',
'green',
]
就是这样 ;)
$str = "lon";
$a = array('london', 'bluehit', 'green', 'lonpark', 'abc', 'aab', 'lonsee');
$b = preg_replace("~^$str~", "\x01", $a);
sort($b);
$b = preg_replace('~\x01~', "lon", $b);
print_r($b);
upd:更简单的是在字符串中预先添加“\x01”而不是替换它。这还允许不区分大小写的匹配或匹配一组字符串:
$str = "lon";
$a = array('london', 'bluehit', 'green', 'Lonpark', 'abc', 'aab', 'lonsee');
$b = preg_replace("~^$str~i", "\x01$0", $a);
sort($b);
$b = str_replace('~\x01~', "", $b);
print_r($b);
usort
和定制比较器非常合适。这是一个具有工厂函数(在本例中为返回函数的函数)的示例,该函数根据所需的前缀生成比较器(使用closures)。
$subject = explode(',', 'london,bluehit,green,lonpark,abc,aab,lonsee');
function make_comparator($prefix)
{
return function ($a, $b) use ($prefix) {
if (strpos($a, $prefix) === 0 && strpos($b, $prefix) !== 0) {
// $a starts with $prefix (and $b does not), sift up
return -1;
} elseif (strpos($a, $prefix) !== 0 && strpos($b, $prefix) === 0) {
// $b starts with $prefix (and $a does not), sift down
return 1;
} else {
// Otherwise, do a normal string comparison
return strcmp($a, $b);
}
};
}
$sorted = $subject;
usort($sorted, make_comparator('lon'));
var_dump($sorted);
对于低于 5.3.0 的 PHP 版本(上述要求),您可以执行类似的操作:
function prefix_comparator($a, $b, $prefix) {
if (strpos($a, $prefix) === 0 && strpos($b, $prefix) !== 0) {
// $a starts with $prefix (and $b does not), sift up
return -1;
} elseif (strpos($a, $prefix) !== 0 && strpos($b, $prefix) === 0) {
// $b starts with $prefix (and $a does not), sift down
return 1;
} else {
// Otherwise, do a normal string comparison
return strcmp($a, $b);
}
}
$sort_by_lon = create_function('$a, $b', 'return prefix_comparator($a, $b, "lon");');
$sorted = $subject;
usort($sorted, $sort_by_lon);
var_dump($sorted);
(行话抱歉)
usort,您可以定义自己的函数来对数据进行排序。
function pref_sort($arr, $pref, $case_insensitive = true)
{
$case_insensitive ? natcasesort($arr) : sort($arr);
$pref_arr = array_filter($arr,
function($val) use ($pref){
return (strpos(strtolower($val), strtolower($pref)) === 0);
});
return array_values($pref_arr + array_diff($arr, $pref_arr));
}
用途:
$pref_str = 'lon';
$array = array('green', 'Lonpark', 'london', 'bluehit', 'abc',
'aab', 'lonsee', 'lon', 'Lon', 'Aab');
// Case-insensitive:
$sorted_array = pref_sort($array, $pref_str);
print_r($sorted_array);
/**
Array
(
[0] => lon
[1] => Lon
[2] => london
[3] => Lonpark
[4] => lonsee
[5] => Aab
[6] => aab
[7] => abc
[8] => bluehit
[9] => green
)
**/
// Case-sensitive:
$sorted_array = pref_sort($array, $pref_str, false);
print_r($sorted_array);
/**
Array
(
[0] => Lon
[1] => Lonpark
[2] => lon
[3] => london
[4] => lonsee
[5] => Aab
[6] => aab
[7] => abc
[8] => bluehit
[9] => green
)
**/
array_multisort()
。循环一次以填充布尔值数组,指示是否在每个字符串的开头找到针字符串。当按升序对布尔值进行排序时,
false
位于
true
之前。然后通过比较整个字符串来打破平局。
代码:(
演示)
$startsWith = 'lon';
array_multisort(
array_map(
fn($w) => !str_starts_with($w, $startsWith),
$array
),
$array
);
var_export($array);