如何在PHP中按主日期键和辅助字母数字排序

时间:2017-02-21 09:10:09

标签: php mongodb sorting date

所以我有一个看起来像这样的2D数组:

[0] => Array(
    [date] => 23-01-2017
    [name] => bbb
    [othertext] => text2
)
[1] => Array(
    [date] => 23-01-2017
    [name] => aaa
    [othertext] => text3
)
[2] => Array(
    [date] => 24-01-2017
    [name] => aaa
    [othertext] => text1
)

注意:此问题未标记为MySQL,使用的数据库是MongoDB,其排序类型为'date' => 'asc'

目前,这是从按日期排序的数据库返回的,但未考虑name属性。我想现在按date对此进行排序,对于具有相同日期的条目,然后按name排序。

我目前的做法是对数据运行array_multisort

array_multisort(
    $array['date'], SORT_STRING,
    $array['name'], SORT_STRING,
    $arrayCopy //<--This copy of the array has the full datetime object
);

但是这会将日期作为字符串排序,所以在某些情况下它会错误地排序;例如1st March会先于2nd Feb。如果将月份放在第一位,那么当Dec / Jan日期排序时,它会错误地排序。

对此有什么正确的解决方法?我已经看到提到usort(),但我不确定如何在这个用例中实现它。 array_multisort是否具有日期功能?

3 个答案:

答案 0 :(得分:1)

在您的数据库查询中:

SELECT * from `your_table_name` order by date asc, name asc;

也许这在mongodb:

 $cursor->sort(array('date' => 1, 'name' => 1));

请参阅:http://php.net/manual/en/mongocursor.sort.php

之后无需在php中执行此操作。

答案 1 :(得分:1)

我强烈建议通过数据库这样做。

但是如果你必须使用usort或者试图理解它是如何工作的:

$arr = [
    [
        'date' => '23-01-2017',
        'name' => 'bbb',
    ],
    [
        'date' => '23-01-2017',
        'name' => 'aaa',
    ],
    [
        'date' => '24-01-2017',
        'name' => 'aaa',
    ],
];

function cmp($a, $b)
{
    $aDate = DateTime::createFromFormat('d-m-Y', $a['date']);
    $bDate = DateTime::createFromFormat('d-m-Y', $b['date']);


    if ($aDate == $bDate) {
        if ($a['name'] == $b['name']) {
            return 0;
        }
        return ($a['name'] < $b['name']) ? -1 : 1;
    }
    return ($aDate < $bDate) ? -1 : 1;
}

usort($arr, "cmp");

print_r($arr);

http://php.net/manual/en/function.usort.php

输出:

[0] => Array
    (
        [date] => 23-01-2017
        [name] => aaa
    )

[1] => Array
    (
        [date] => 23-01-2017
        [name] => bbb
    )

[2] => Array
    (
        [date] => 24-01-2017
        [name] => aaa
    )

答案 2 :(得分:1)

使用usort-function,您可以:

$foo = array(
  0 => array(
    "date" => "23-01-2017",
    "name" => "bbb",
    "othertext" => "text2"
  ),
  1 => array(
    "date" => "23-01-2017",
    "name" => "aaa",
    "othertext" => "text3"
  ),
  2 => array(
    "date" => "24-01-2017",
    "name" => "aaa",
    "othertext" => "text1"
  )
);

usort($foo, function($a, $b)
{
  return $a["date"] === $b["date"] ? strcmp($a["name"], $b["name"]) : strcmp(strtotime($a["date"]), strtotime($b["date"]));
});

var_dump($foo);