按值排序数组,保持键值不变

时间:2013-08-09 17:53:43

标签: php

我正在查看PHP数组排序函数,以找到一些方法来执行以下操作,但似乎无法管理它。

实施例

Array ( 
[77] => 79
[72] => 78
[71] => 78
[82] => 79
[76] => 79
[73] => 78
[75] => 78 )

我想重新订购

Array ( 
[72] => 78
[71] => 78
[73] => 78
[75] => 78
[77] => 79
[82] => 79
[76] => 79 )

注意关键点是否尊重他们原来的顺序,他们只是根据价值排列(因此79中第一个77仍然是79中的第一个等)

我认为aasort会起作用,但它没有

asort($categories);
foreach ($categories as $key => $val) {
    echo "$key = $val\n";
    echo "<br>";
}

输出(请原谅等号)

74 = 78
85 = 78
75 = 78
73 = 78
70 = 78
71 = 78
72 = 78
82 = 79
86 = 79
81 = 79
77 = 79
80 = 79
76 = 79 

4 个答案:

答案 0 :(得分:3)

可能有可能将其整合到Mark建议的一些冒泡排序实现中,但是速度会有一个权衡。如果速度不是一个问题,那么这是一个天真的实现,可以做你想要的。

它只是依赖于哪些键用于特定值,然后确保最终排序的数组符合该顺序:

function sort_keys_intact(&$a) {
    $b = array();
    $values = array();
    foreach ( $a as $k => $v ) {
        $values[$v][] = $k;
    }
    asort($a);
    $used = 0;
    foreach ( $a as $k => $v ) {
        if ( $used == count($values[$v]) + 1 ) {
            $used = 0;
        }
        $b[$values[$v][$used]] = $v;
        $used++;
    }
    $a = $b;
}

试运行

echo 'Before:' . PHP_EOL;
print_r($categories);
sort_keys_intact($categories);
echo 'After:' . PHP_EOL;
print_r($categories);

输出

Before:
Array
(
    [77] => 79
    [72] => 78
    [71] => 78
    [82] => 79
    [76] => 79
    [73] => 78
    [75] => 78
)
After:
Array
(
    [72] => 78
    [71] => 78
    [73] => 78
    [75] => 78
    [77] => 79
    [82] => 79
    [76] => 79
)

答案 1 :(得分:0)

不熟悉PHP,所以不确定如何在PHP中执行此操作(可能就是问题),但您可以创建第二个列表,如下所示:

[77] => (79,1)
[72] => (78,2)
[71] => (78,3)
[82] => (79,4)
[76] => (79,5)
[73] => (78,6)
[75] => (78,7)

这是一个包含原始值和订单值的元组。做一个排序,然后删除每个的排序,以产生所需的格式。

答案 2 :(得分:0)

我做这样的事情:

function my_sort(&$array)
{
  $i = 0;
  foreach ($array as &$val)
    $val = [$i++, $val];

  uasort($array, function($a, $b) {
    return $a[1] - $b[1] ?: $a[0] - $b[0];
  });

  foreach ($array as &$val)
    $val = $val[1];
}

我认为这只是@ Nuclearman的回答。

这假设所有值都是整数。如果情况并非如此,则您必须更改$a[1] - $b[1]以反映值的排序方式。 (如果值相同,则sort函数返回$a[0] - $b[0]。)

答案 3 :(得分:0)

答案对我没有用,所以我写了一个函数来解决这个问题:

function sort_value_leave_key(&$arr){

$z = array();
foreach ($arr as $k => $v){
    $z[$v.rand(1111,9999)] = $k;
}
krsort($z);

$arr = array();
foreach($z as $k => $v){
    $arr[$v] = substr($k,0,-4);
}

}