[英]PHP - Sort multi-dimensional array by another array
我正在嘗試按另一個數組對多維數組進行排序,但到目前為止還不夠。
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 中沒有內置函數,我無法想到任何自定義函數,它可以使用 usort 來做到這一點。 但是array_map已經足夠簡單了,imo,為什么不使用它呢?
$sorted = array_map(function($v) use ($data) {
return $data[$v - 1];
}, $order);
這就是我要做的。 我會結合 $data 數組使用自定義 usort 函數 (arr_sort)。
<?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>";
對於那些想要根據具有實際 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"
}
}
您可以嘗試對usort()使用自定義排序。 這樣您就可以使用第一個數組來確定第二個數組的順序。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.