我正在尝试按另一个数组对多维数组进行排序,但到目前为止还没有。array_multisort
似乎只适用于真正的排序。
假设我有这两个数组
$order = array(2,3,1);
$data = array(
array('id' => 1, 'title' => 'whatever'),
array('id' => 2, 'title' => 'whatever'),
array('id' => 3, 'title' => 'whatever')
);
现在我想根据我的$order
数组的顺序来排序我的$data
数组。
这是我想要的结果:
$data = array(
array('id' => 2, 'title' => 'whatever'),
array('id' => 3, 'title' => 'whatever')
array('id' => 1, 'title' => 'whatever'),
);
我可以通过运行一个嵌套循环轻松地完成这一点,但这不会很好地扩展(我的数组相当大,数组有更多的字段)。
在您的示例中,$data数组中的id是连续编号的,从1开始。我下面给出的代码假设情况总是如此。如果不是这种情况,代码将不起作用。
$result = array();
$index = 0;
foreach ($order as $position) {
$result[$index] = $data[$position - 1];
$index++;
}
在http://codepad.org/YC8w0yHh您可以看到它适用于您的示例数据。
编辑
如果上面的假设不成立,下面的代码将获得相同的结果:
<?php
$data = array(
array('id' => 1, 'title' => 'whatever'),
array('id' => 2, 'title' => 'whatever'),
array('id' => 3, 'title' => 'whatever')
);
$order = array(2,3,1);
$order = array_flip($order);
function cmp($a, $b)
{
global $order;
$posA = $order[$a['id']];
$posB = $order[$b['id']];
if ($posA == $posB) {
return 0;
}
return ($posA < $posB) ? -1 : 1;
}
usort($data, 'cmp');
var_dump($data);
参见http://codepad.org/Q7EcTSfs。
通过在$order数组上调用array_flip(),它可以用于位置查找。这类似于哈希表查找,它在时间上是线性的,或者说是O(n)。你做得再好不过了。
在PHP中没有内置函数,我无法想到任何自定义函数,这将使用ussort来完成此操作。但是array_map已经足够简单了,所以为什么不用它呢?
$sorted = array_map(function($v) use ($data) {
return $data[$v - 1];
}, $order);
对于那些希望基于具有实际id的数组而不是基于具有索引的数组(如接受的答案中所示)对数据进行排序的人,您可以使用以下usort
的简单比较函数:
usort($data, function($a, $b) use ($order) {
$posA = array_search($a['id'], $order);
$posB = array_search($b['id'], $order);
return $posA - $posB;
});
所以下面的例子将工作得很好,你不会得到Undefined offset
通知和null
值的数组:
$order = [20, 30, 10];
$data = [
['id' => 10, 'title' => 'Title 1'],
['id' => 20, 'title' => 'Title 2'],
['id' => 30, 'title' => 'Title 3']
];
usort($data, function($a, $b) use ($order) {
$posA = array_search($a['id'], $order);
$posB = array_search($b['id'], $order);
return $posA - $posB;
});
echo '<pre>', var_dump($data), '</pre>';
输出:array(3) {
[0]=>
array(2) {
["id"]=>
int(20)
["title"]=>
string(7) "Title 2"
}
[1]=>
array(2) {
["id"]=>
int(30)
["title"]=>
string(7) "Title 3"
}
[2]=>
array(2) {
["id"]=>
int(10)
["title"]=>
string(7) "Title 1"
}
}
我就是这么做的。我将使用自定义排序函数(arr_sort)与$data数组结合使用。
<?php
$order = array(2,3,1);
$data = array(
array('id' => 1, 'title' => 'whatever'),
array('id' => 2, 'title' => 'whatever'),
array('id' => 3, 'title' => 'whatever')
);
function arr_sort($a,$b){
global $order;
foreach ($order as $key => $value) {
if ($value==$a['id']) {
return 0;
break;
}
if ($value==$b['id']) {
return 1;
break;
}
}
}
usort($data,'arr_sort');
echo "<pre>";
print_r($data);
echo "<pre>";
您可以尝试使用usort()自定义排序。这样,您就可以使用第一个数组来确定第二个数组的顺序。