按自定义顺序对数组的 php 数组进行排序

我有一个数组数组:

Array ( 
    [0] => Array (
        [id] = 7867867,
        [title] = 'Some Title'),
    [1] => Array (
        [id] = 3452342,
        [title] = 'Some Title'),
    [2] => Array (
        [id] = 1231233,
        [title] = 'Some Title'),
    [3] => Array (
        [id] = 5867867,
        [title] = 'Some Title')
)

需要按特定顺序进行:

  1. 3452342
  2. 5867867
  3. 7867867
  4. 1231233

我该怎么做呢?我以前对数组进行排序,并阅读了很多关于它的其他帖子,但它们总是基于比较的(即 valueA < valueB)。

感谢您的帮助。


答案 1

您可以使用 来精确指定数组的排序方式。在这种情况下,数组可以在比较函数中使用。usort()$order

下面的示例使用闭包来简化工作。

$order = array(3452342, 5867867, 7867867, 1231233);
$array = array(
    array('id' => 7867867, 'title' => 'Some Title'),
    array('id' => 3452342, 'title' => 'Some Title'),
    array('id' => 1231233, 'title' => 'Some Title'),
    array('id' => 5867867, 'title' => 'Some Title'),
);

usort($array, function ($a, $b) use ($order) {
    $pos_a = array_search($a['id'], $order);
    $pos_b = array_search($b['id'], $order);
    return $pos_a - $pos_b;
});

var_dump($array);

这项工作的关键是将要比较的值是数组中s的位置。id$order

比较函数的工作原理是查找要在数组中比较的两个项目的 ID 的位置。如果在数组中位于前面,则函数的返回值将为负(小于,因此“浮点”到顶部)。如果之后出现,则该函数返回一个正数(大于,因此“下沉”)。$order$a['id']$b['id']$order$a$a['id']$b['id']$a

最后,使用闭包没有特殊原因;这只是我快速编写这些一次性函数的首选方式。它同样可以使用正常的命名函数。


答案 2

扩展萨拉特对此附加要求的答案:

现在,当我将项添加到数组而不是排序时会发生什么情况?我不在乎它们出现的顺序,只要它出现在我指定的顺序之后。

您需要在排序功能中添加两个附加条件:

  1. “不关心”项目必须被视为大于列入白名单的项目
  2. 两个“不在乎”的项目必须被视为相等

因此,修改后的代码将是:

$order = array(
    3452342,
    5867867,
    7867867,
    1231233
);
$array = array(
    array("id" => 7867867, "title" => "Must Be #3"),
    array("id" => 3452342, "title" => "Must Be #1"),
    array("id" => 1231233, "title" => "Must Be #4"),
    array("id" => 5867867, "title" => "Must Be #2"),
    array("id" => 1111111, "title" => "Dont Care #1"),
    array("id" => 2222222, "title" => "Dont Care #2"),
    array("id" => 3333333, "title" => "Dont Care #3"),
    array("id" => 4444444, "title" => "Dont Care #4")
);

shuffle($array);  // for testing
var_dump($array); // before

usort($array, function ($a, $b) use ($order) {
    $a = array_search($a["id"], $order);
    $b = array_search($b["id"], $order);
    if ($a === false && $b === false) { // both items are dont cares
        return 0;                       // a == b
    } else if ($a === false) {          // $a is a dont care
        return 1;                       // $a > $b
    } else if ($b === false) {          // $b is a dont care
        return -1;                      // $a < $b
    } else {
        return $a - $b;                 // sort $a and $b ascending
    }
});
var_dump($array); // after

输出:

Before                         |  After
-------------------------------+-------------------------------
array(8) {                     |  array(8) {
  [0]=>                        |    [0]=>
  array(2) {                   |    array(2) {
    ["id"]=>                   |      ["id"]=>
    int(4444444)               |      int(3452342)
    ["title"]=>                |      ["title"]=>
    string(12) "Dont Care #4"  |      string(10) "Must Be #1"
  }                            |    }
  [1]=>                        |    [1]=>
  array(2) {                   |    array(2) {
    ["id"]=>                   |      ["id"]=>
    int(3333333)               |      int(5867867)
    ["title"]=>                |      ["title"]=>
    string(12) "Dont Care #3"  |      string(10) "Must Be #2"
  }                            |    }
  [2]=>                        |    [2]=>
  array(2) {                   |    array(2) {
    ["id"]=>                   |      ["id"]=>
    int(1231233)               |      int(7867867)
    ["title"]=>                |      ["title"]=>
    string(10) "Must Be #4"    |      string(10) "Must Be #3"
  }                            |    }
  [3]=>                        |    [3]=>
  array(2) {                   |    array(2) {
    ["id"]=>                   |      ["id"]=>
    int(1111111)               |      int(1231233)
    ["title"]=>                |      ["title"]=>
    string(12) "Dont Care #1"  |      string(10) "Must Be #4"
  }                            |    }
  [4]=>                        |    [4]=>
  array(2) {                   |    array(2) {
    ["id"]=>                   |      ["id"]=>
    int(5867867)               |      int(2222222)
    ["title"]=>                |      ["title"]=>
    string(10) "Must Be #2"    |      string(12) "Dont Care #2"
  }                            |    }
  [5]=>                        |    [5]=>
  array(2) {                   |    array(2) {
    ["id"]=>                   |      ["id"]=>
    int(2222222)               |      int(1111111)
    ["title"]=>                |      ["title"]=>
    string(12) "Dont Care #2"  |      string(12) "Dont Care #1"
  }                            |    }
  [6]=>                        |    [6]=>
  array(2) {                   |    array(2) {
    ["id"]=>                   |      ["id"]=>
    int(3452342)               |      int(3333333)
    ["title"]=>                |      ["title"]=>
    string(10) "Must Be #1"    |      string(12) "Dont Care #3"
  }                            |    }
  [7]=>                        |    [7]=>
  array(2) {                   |    array(2) {
    ["id"]=>                   |      ["id"]=>
    int(7867867)               |      int(4444444)
    ["title"]=>                |      ["title"]=>
    string(10) "Must Be #3"    |      string(12) "Dont Care #4"
  }                            |    }
}                              |  }