PHP按子集排序数组

时间:2011-06-27 22:10:43

标签: php arrays sorting subset

我有两个阵列。

一个是更大的数据:

Array
(
    [12] => blah
    [36] => foo
    [58] => blah
    [60] => blah
    [72] => blah
    [90] => bar
)

另一个是不同但相关数据的较小子集,顺序不同,每个键对应于较大数组中的相同键:

Array
(
    [36] => foo data
    [90] => bar data
    [12] => blah data
)

现在,我的问题是,如何让第一个数组处于这样的顺序,以便第一个数组中第二个数组中具有相应键的键将首先出现,并且与第二个数组的顺序相同?

因此,像这样:

Array
(
    [36] => foo
    [90] => bar
    [12] => blah
    [58] => blah
    [60] => blah
    [72] => blah
)

4 个答案:

答案 0 :(得分:5)

简单的O(n)解决方案。

$arr1 = array(12 => 1, 36 => 2, 58 => 3, 60 => 4, 72 => 5);
$arr2 = array(36 => 1, 60 => 2, 12 => 1);

$result = array();

foreach($arr2 as $key => $value) {
    $result[$key] = $arr1[$key];
    unset($arr1[$key]);
}

foreach($arr1 as $key => $value) {
    $result[$key] = $arr1[$key];
}

var_dump($result);

输出:

array(5) {
  [36]=>
  int(2)
  [60]=>
  int(4)
  [12]=>
  int(1)
  [58]=>
  int(3)
  [72]=>
  int(5)
}

答案 1 :(得分:2)

使用uksort

编辑:修正了malko指出的语法/逻辑错误。谢谢。

$array_to_sort = array
(
    12 => "blah",
    36 => "foo",
    58 => "blah",
    60 => "blah",
    72 => "blah",
    90 => "bar"
);

$sorted_array = array(
    36 => "foo data",
    90 => "bar data",
    12 => "blah data"
);

global $sorted_array_keys;
$sorted_array_keys = array_keys($sorted_array);

function cmp($a, $b)
{
    global $sorted_array_keys;
    $a_in_array = in_array($a, $sorted_array_keys);
    $b_in_array = in_array($b, $sorted_array_keys);
    if ($a_in_array && $b_in_array) {
        return array_search($a, $sorted_array_keys) - array_search($b, $sorted_array_keys);
    } else if ( $a_in_array ) {
        return -1;
    } else {
        return 1;
    }
}

uksort ( $array_to_sort , cmp );
print_r($array_to_sort);

这开始很干净,但结果非常丑陋和不清楚。我现在倾向于其他一些答案,而不是我的答案。

答案 2 :(得分:2)

这是一个使用带闭包的uksort的例子,我认为它应该在大阵列上更有效,但我没有做任何基准,所以......难以真正确认无测试。

$a = array(
    12 => 'blah'
    ,36 => 'foo'
    ,58 => 'blah'
    ,60 => 'blah'
    ,72 => 'blah'
    ,90 => 'bar'
);

$b = array(
    36 => 'foo data'
    ,90 => 'bar data'
    ,12 => 'blah data'
);

$keysPosition = array_flip(array_keys($b));
uksort($a,function($a,$b) use ($keysPosition){
    if(isset($keysPosition[$a],$keysPosition[$b])){
        return $keysPosition[$a]>$keysPosition[$b]?1:-1;
    }else if( isset($keysPosition[$a]) ){
        return -1;
    }else if( isset($keysPosition[$b]) ){
        return 1;
    }
    return 0;
});

print_r($a);

结果:

Array
(
    [36] => foo
    [90] => bar
    [12] => blah
    [72] => blah
    [58] => blah
    [60] => blah
)

如果你不能使用闭包(php< 5.3)你可以使用全局做类似的东西,但它根本不干净。

答案 3 :(得分:1)

$array1 = array(12 => 1, 36 => 2, 58 => 3, 60 => 4, 72 => 5);
$array2 = array(36 => 1, 60 => 2, 12 => 1);

# obtaining keys in the order of question    
$result = array_intersect_key($array2, $array1);

# assign values from original $array1
foreach($result as $key => &$value) {
    $value = $array1[$key];
}
unset($value); # kill reference for safety

# add missing elements from $array1
$result += $array1;

var_dump($result);

输出:

array(5) {
  [36]=>
  int(2)
  [60]=>
  int(4)
  [12]=>
  int(1)
  [58]=>
  int(3)
  [72]=>
  int(5)
}

有关数组的+,请参阅Array Operators