如何按照给定的顺序重新排序一个数组?

segmentfault上有人提了个问题,关于数组排序的,原本感觉很简单,但是我还是踩到了php自带函数的几个坑……

<?php
$a = array(
    '1' => 'one',
    '2' => 'two',
    '3' => 'three',
    '4' => 'four',
    '5' => 'five'
);
$b = array(2,5,4,1,3); // 数组a的key顺序
//给定数组a和b,不用循环,如何排序成数组c?
$c = array(
    '2' => 'two',
    '5' => 'five',
    '4' => 'four',
    '1' => 'one',
    '3' => 'three'
);

这个题目并不难,如果用循环的话,不用动脑就能写出来:

$a = array(
    '1' => 'one',
    '2' => 'two',
    '3' => 'three',
    '4' => 'four',
    '5' => 'five'
);
$b = array(2,5,4,1,3);
$c = array();
foreach ($b as $v) {
    $c[$v] = $a[$v];
}
print_r($c);

如果不使用循环的话,我脑子里面第一个浮现出来的就是用array_merge这个函数,代码如下:

$a = array(
    '1' => 'one',
    '2' => 'two',
    '3' => 'three',
    '4' => 'four',
    '5' => 'five'
);
$b = array(2,5,4,1,3);
$_b=array_flip($b);//将数组的key和value互换
print_r( array_merge( $_b , $a ) );

**array_merge($a,$b)**的功能是将两个数组合并,如果key相同,则后面一个数组的值覆盖前面一个.本以为能得到想要的结果,没想到结果如下:

Array
(
    [0] => 0
    [1] => 1
    [2] => 2
    [3] => 3
    [4] => 4
    [5] => one
    [6] => two
    [7] => three
    [8] => four
    [9] => five
)

这结果似乎是舍弃了key,直接把两个数组的值压入新数组了.查了一下发现,当数组的下标是数字的时候,array_merge()会无视这些数字,直接压入新数组,比如:

$a=array('1'=>'a','2'=>'b','3'=>'c','x'=>'d');
$b=array('3'=>'cc','x'=>'dd','5'=>'ee','6'=>'ff');
print_r(array_merge($a,$b));

结果是:

Array
(
    [0] => a
    [1] => b
    [2] => c
    [x] => dd
    [3] => cc
    [4] => ee
    [5] => ff
)

所以这个方法行不通.

最后我想到了 array_walk($arr,$function) 这个函数,通过如下方法:

$a = array(
    '1' => 'one',
    '2' => 'two',
    '3' => 'three',
    '4' => 'four',
    '5' => 'five'
);
$b = array('2','5','4','1','3');
$result=array();
function sort_key($v){
	global $result;
	global $a;
	$result[$v]=$a[$v];
}
array_walk($b, 'sort_key');

结果可行.

Comments

comments powered by Disqus