真的只是为了好玩。我很好奇做到这一点的最佳方法。
这是一种方法(很可能有更好的解决方案):
function sort_length($str1, $str2)
{
if(strlen($str1) == strlen($str2))
{
return 0;
}
return strlen($str1) > strlen($str2) ? -1 : 1;
}
$words = array("Hello", "World", "this", "is", "a", "test");
usort($words, 'sort_length');
$new_list = array();
$boolean = true;
foreach($words as $word)
{
if($boolean)
{
array_push($new_list, $word);
}
else
{
array_unshift($new_list, $word);
}
$boolean = !$boolean;
}
//print_r($new_list);
我会做以下事情:
这是保留数组键的解决方案:
// function to compare two strings by their length
function cmp_strlen($a, $b) {
return strlen($a) - strlen($b);
}
// sort array by length while preserving the keys
uasort($arr, 'cmp_strlen');
$ordered = array();
$keys = array_keys($arr);
// fill $ordered with odd keys in order
for ($i=0, $n=count($keys); $i<$n; $i+=2) {
$ordered[$keys[$i]] = $arr[$keys[$i]];
}
// fill $ordered with even keys in reverse order
for ($i=((count($keys)>>1)<<1)-1; $i>0; $i-=2) {
$ordered[$keys[$i]] = $arr[$keys[$i]];
}
第一次尝试可能是先按正常方式对它们进行排序。然后迭代该数组,复制到一个新数组,复制目标在新数组的开头和结尾之间交替,其中开始索引递增,结束索引递减。
使用两个连续的排序算法以避免生成临时数组。首先按 str 长度排序,第二次按键排序,以便偶数键排在前面,然后奇数键在末尾按降序排序。
代码:(演示)
$array = ["Hello", "World", "this", "is", "a", "test"];
array_multisort(array_map('strlen', $array), $array);
uksort(
$array,
fn($a, $b) => ($isOdd = $a & 1) <=> ($b & 1) // sort evens before odds
?: ($isOdd ? -1 : 1) * ($a <=> $b) // sort evens ASC and odds DESC
);
var_export($array);
输出:
array (
0 => 'a',
2 => 'test',
4 => 'Hello',
5 => 'World',
3 => 'this',
1 => 'is',
)
如果您希望对键建立索引,请对结果调用
array_values()
。
或者,
array_multisort()
可以被调用两次;首先是值,然后是键。这使用 array_map()
将上述脚本的双宇宙飞船比较替换为键的两次完整迭代,但结果数组的键已建立索引。 (演示)
array_multisort(array_map('strlen', $array), $array);
$keys = array_keys($array);
array_multisort(
array_map(fn($k) => $k & 1, $keys),
array_map(fn($k) => ($k & 1 ? -1 : 1) * $k, $keys),
$array
);
var_export($array);
输出:
array (
0 => 'a',
1 => 'test',
2 => 'Hello',
3 => 'World',
4 => 'this',
5 => 'is',
)