按日期时间列降序对多维数组进行排序[重复]

问题描述 投票:0回答:5

我需要按 getNotifications 函数中的“start_date”值 DESC 顺序对通知数组进行排序:

$posts_id_arr = getPoststIds($conn);

foreach ($posts_id_arr as $key => $val) {
  $total_arr[$key] = [
    'notification' => getNotifications($val['post_id'], $user_id, $conn)
  ];
}

$response_array = array('data' => $total_arr, 'more things' => $more_array);
echo json_encode($response_array);

现在由于 foreach 循环,订单是按帖子 id 排序的。

data {
       notification: 
      [
       {
        post_id: “1",
        start_date: "2016-10-10 08:00:00",
       },
       {
        post_id: “1",
        start_date: "2016-10-10 12:00:00",
       }
    ],
     notification:
      [
        post_id: “2",
        start_date: "2016-10-10 09:00:00",
       },
       {
        post_id: “2",
        start_date: "2016-10-10 13:00:00",
       }
    ]
}

我需要它是 1: 08:00、2: 09:00、1: 12:00、2: 13:00

php arrays sorting datetime multidimensional-array
5个回答
2
投票

您可以使用自定义函数 uasort 对数组中的值进行排序。您的日期格式可以使用

strcmp
进行排序 - 过去的日期低于未来的日期,因此您可以在比较器中使用它。

function sort_by_date($a, $b) {
  return strcmp($a->start_date, $b->start_date);
}

$sorted_posts = uasort($total_arr->notification, 'sort_by_date');

$response_array = array('data' => $sorted_posts, 'more things' => $more_array);

0
投票

但是,您不需要在

foreach
内执行排序。

您可以尝试以下代码。相应地更改变量名称。

foreach ($points as $key => $val) {
    $time[$key] = $val[0];
}

array_multisort($time, SORT_ASC, $points);

这是因为

array_multisort
的工作方式。它对多个数组进行排序,当
$time
数组排序时,$points 数组会根据 $time 中的数组索引重新排序。不过 array_multisort 应该在 foreach 之后
希望这会有所帮助。


0
投票

如果您想使用内部数组进行排序,您可以更好地选择

usort()
方法。

usort — 使用用户定义的比较函数按值对数组进行排序

此函数将使用用户提供的比较函数按数组的值对数组进行排序。如果您希望排序的数组需要按某些重要标准进行排序,则应该使用此函数。

<?php
function cmp($a, $b)
{
    return strcmp($a["fruit"], $b["fruit"]);
}

$fruits[0]["fruit"] = "lemons";
$fruits[1]["fruit"] = "apples";
$fruits[2]["fruit"] = "grapes";

usort($fruits, "cmp");

while (list($key, $value) = each($fruits)) {
    echo "\$fruits[$key]: " . $value["fruit"] . "\n";
}
?>

对多维数组进行排序时,

$a
$b
包含对数组第一个索引的引用。

上面的例子将输出:

$fruits[0]: apples
$fruits[1]: grapes
$fruits[2]: lemons

替代解决方案:

您可以尝试

array_multisort()
,因为它会根据您需要的顺序对数组进行排序。

$arr  = your array;
$sort = array();
foreach($arr as $k=>$v) {
    $sort['field'][$k] = $v['field'];
}

array_multisort($sort['field'], SORT_DESC, $arr);

echo "<pre>";
print_r($arr);

0
投票

您可以按照以下步骤操作:

1)定义一个临时数组来存储日期:

foreach ($total_arr['notification'] as $vals) {
    $temp_dates[] = $vals['start_date'];
}

2) 使用

arsort()
:

对新创建的临时数组进行排序
arsort($temp_dates);

3)使用

array_filter()
并循环查找相应的帖子ID并存储到结果数组中:

$i = 0;
foreach ($total_arr['notification'] as $vals) {
    $res['notification'][] = array_filter($vals, function($val) {
        return $val['start_date'] == $temp_dates[$i];
    });
    $i++;
}

$response_array = array('data' => $res, 'more things' => $more_array);

注意:不确定它是否适用于重复的

start_date


0
投票

正如 iblamefish 提到的,使用

uasort()
是可行的方法 - 与所有其他答案相比,它很简单,内存和处理效率都很高。但是,虽然
strcmp()
确实为您拥有的 SQL 样式日期产生了良好的结果,但这并不是处理时间字段的“正确”方法 - 您应该解析时间并将它们作为时间值进行比较:

$a = [
  [ "name" => "foo", "date" => "2016-08-09 10:30:00" ],
  [ "name" => "bar", "date" => "2016-01-09 02:00:00" ],
  [ "name" => "baz", "date" => "2016-11-02 18:21:34" ]
];
uasort($a, function($a,$b) {
  return (new DateTime($a->date))->getTimestamp() - (new DateTime($b->date))->getTimestamp();
});
var_dump($a);

产生:

array(3) {
  [0] =>
  array(2) {
    'name' =>
    string(3) "foo"
    'date' =>
    string(19) "2016-08-09 10:30:00"
  }
  [1] =>
  array(2) {
    'name' =>
    string(3) "bar"
    'date' =>
    string(19) "2016-01-09 02:00:00"
  }
  [2] =>
  array(2) {
    'name' =>
    string(3) "baz"
    'date' =>
    string(19) "2016-11-02 18:21:34"
  }
}

此外,闭包(匿名函数)比使用旧式的“文本可调用对象”更有趣。

© www.soinside.com 2019 - 2024. All rights reserved.