簡體   English   中英

PHP - 按另一個數組對多維數組進行排序

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM