我有以下类型的数组:
$foo = array(
"a" => 1,
"b" => 1,
"c" => 2,
"d" => 2,
"e" => 3,
"f" => 3,
"g" => 4,
"h" => 4,
"i" => 5,
"j" => 5,
"k" => 10,
"l" => 12,
"m" => 15,
"n" => 20
);
我需要以这种方式对数组进行排序:
$foo = array(1,2,3,4,5,12,20,15,10,5,4,3,2,1);
如您所见,最佳值需要位于数组的中间。以及数组开头/结尾的最小值。密钥需要链接到原始值。
感谢您的帮助!对不起我的英语。
如果输入已经排序,您可以使用两个循环首先将每个具有奇数偏移量的项目按升序推送,然后将每个具有偶数偏移量的项目按降序推送到数组中:
$keys = array_keys($foo);
$n = count($keys);
$result = array();
for ($i=0; $i<$n; $i+=2) {
$result[$keys[$i]] = $foo[$keys[$i]];
}
for ($i=$n-$n%2-1; $i>0; $i-=2) {
$result[$keys[$i]] = $foo[$keys[$i]];
}
首先将所有整数按升序排列。 假设 $foo_as 是您按升序排列的新数组。
$a=a new empty array of size $n
$n=number of integers.
$c=0;
for ($i=$n-1;$i>0;$i--){
if (i%2==0){
$a(i/2)+c=$foo_as($n-$c)
}
else{
$a(i+1/2)-c=$foo_as($n-$c)
}
$c++
}
说明:我将最大的整数放在中间。之后,我按降序填充中间索引周围的备用索引。
- - - - - 11 - - - - -
- - - - 10 11 - - - - -
- - - - 10 11 9 - - - -
- - - 8 10 11 9 - - - -
- - - 8 10 11 9 7 - - -
- - 6 8 10 11 9 7 - - -
- - 6 8 10 11 9 7 5 - -
- 4 6 8 10 11 9 7 5 - -
- 4 6 8 10 11 9 7 5 3 -
2 4 6 8 10 11 9 7 5 3 -
2 4 6 8 10 11 9 7 5 3 1
我使用了一个基本算法来演示这一点。如果在某些时候,我的
php
语法不正确,请忽略它。
一个矫枉过正的版本:
<?php
$foo = array(
"a" => 1,
"b" => 1,
"c" => 2,
"d" => 2,
"e" => 3,
"f" => 3,
"g" => 4,
"h" => 4,
"i" => 5,
"j" => 5,
"k" => 10,
"l" => 12,
"m" => 15,
"n" => 20
);
$arrayKeys = array_keys($foo);
$arrayValues = array_values($foo);
$array_count = count($foo);
for ($idx =0; $idx < round($array_count/2); $idx+=2) {
$tmpA = $arrayKeys[$idx];
$arrayKeys[$idx] = $arrayKeys[$array_count - $idx -1];
$arrayKeys[$array_count - $idx -1] = $tmpA;
$tmpB = $arrayValues[$idx];
$arrayValues[$idx] = $arrayValues[$array_count - $idx -1];
$arrayValues[$array_count - $idx -1] = $tmpB;
}
$tmpArray = array_combine($arrayKeys, $arrayValues);
$ascent = array_slice($tmpArray, 0, round($array_count/2));
$descent = array_slice($tmpArray, round($array_count/2));
asort($ascent);
arsort($descent);
$foobar = array_merge($ascent, $descent);
var_dump($foo, $foobar);
?>
使用单个循环并按计算出的关键位置填充临时排序数组。
array_multisort()
甚至会保留非数字关联键;如果需要,请对结果调用 array_values()
。
代码:(演示)
array_multisort(
array_map(fn($k) => ($k & 1) ? PHP_INT_MAX - $k : $k, array_keys(array_values($foo))),
$foo
);
var_export($foo);
或者按非奇数/奇数索引进行分组,然后反转第二个子数组,然后合并。 (演示)
$grouped = [[], []];
foreach (array_values($foo) as $i => $v) {
$grouped[(int) $i & 1][] = $v;
}
$grouped[1] = array_reverse($grouped[1]);
var_export(
array_merge(...$grouped)
);