注意:我编辑了这个示例,并用1替换了所有值。值不重要,只有键重要。我以前写的值导致了误解。对不起
注意:a/b块总是连续的。我添加这个是因为它不清楚。如果存在3a/3b和5a/5b,则总是存在4a/4b,而不仅仅是4。
我的数组包含带前导零的编号键。有时,这些带编号的键有两种变体,我通过使用后缀a和b来区分。带变体或不带变体的键的数量是未知的,但永远不会超过2位数字;即最高的数字键是"09"。
问题是,这些数组键需要用数字排序,但当存在后缀时,这些后缀应该优先。单独使用ksort()并不能实现这一点。
例如,ksort()给我的是:
$arr = array(
'01' => 1,
'02' => 1,
'03a' => 1,
'03b' => 1,
'04a' => 1,
'04b' => 1,
'05a' => 1,
'05b' => 1,
'06' => 1,
);
但是,我需要这个:
$arr = array(
'01' => 1,
'02' => 1,
'03a' => 1,
'04a' => 1,
'05a' => 1,
'03b' => 1,
'04b' => 1,
'05b' => 1,
'06' => 1,
);
我用一些花哨的编码体操来获得我想要的东西,但它并不漂亮。我想知道是否有更好、更干净的方法?
这是我的工作。
1) 我使用ksort(),它给出了上面两个数组中的第一个。(那个还不是我想要的。)
2) 我创建了两个数组。一个用于'a'后缀,另一个用于b'后缀。
$arr_a = array();
$arr_b = array();
foreach ($arr as $k => $v) {
if (substr($k, 2) == 'a') {
$arr_a[$k] = $v;
} else if (substr($k, 2) == 'b') {
$arr_b[$k] = $v;
}
}
3) 我合并了两个后缀数组。
$arr_suffixes = array_merge($arr_a, $arr_b);
4) 我将原始数组进行切片,这样我就得到了后缀之前的部分和后缀之后的部分。
$i = array_search(key($arr_suffixes), array_keys($arr));
$length = count($arr_suffixes);
$arr_before_suffixes = array_slice($arr, 0, $i);
$arr_after_suffixes = array_slice($arr, $i + $length);
5) 使用array_merge,我重新组合切片数组以创建我需要的数组。
$arr = array_merge($arr_before_suffixes, $arr_suffixes);
$arr = array_merge($arr, $arr_after_suffixes);
最后,我们得到了正确的$arr。难道没有更好的方法吗?感觉真的很难看。
您没有正式的规则。我试着猜测。
$arr = array(
'01' => 1,
'02' => 1,
'03a' => 1,
'03b' => 1,
'04a' => 1,
'04b' => 1,
'05a' => 1,
'05b' => 1,
'06' => 1,
);
uksort($arr, function($item1, $item2)
{
$last1 = substr($item1, -1);
$last2 = substr($item2, -1);
// one of the items is a number or last letters matches
if (is_numeric($last1) || is_numeric($last2) || $last1 == $last2)
// simple number comparison
return $item1 - $item2;
else
// natural order comparison
return $last1 > $last2 ? 1 : -1;
});
var_dump($arr);
natsort()函数将帮助您:
$arr = array(
'01' => 1,
'02' => 1,
'03a' => 1,
'03b' => 1,
'04a' => 1,
'04b' => 1,
'05a' => 1,
'05b' => 1,
'06' => 1,
);
$keys = array_keys($arr);
natsort($keys);
$result = array();
foreach ($keys as $key) {
$result[$key] = $arr[$key];
}
print_r($result); // Your expected result
$arr = array(
'01' => 1,
'02' => 2,
'03a' => 3,
'03b' => 6,
'04a' => 4,
'04b' => 7,
'05a' => 5,
'05b' => 8,
'06' => 9,
);
uksort(
$arr,
function($a, $b) {
sscanf($a, '%d%s', $an, $as);
sscanf($b, '%d%s', $bn, $bs);
if ($as === null || $bs === null || $as === $bs) {
return $an - $bn;
}
return strcmp($as, $bs);
}
);
var_dump($arr);