【问题标题】:Sort by php array按php数组排序
【发布时间】:2017-02-18 13:15:18
【问题描述】:

我需要通过 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

【问题讨论】:

  • 我认为你应该在循环之后对数据进行排序,这会很有帮助并且需要更少的迭代。
  • @Gilad Adar。您是否尝试过我的解决方案。如果不尝试分享想法,如果您遇到任何障碍,请告诉我,以便我们纠正它。

标签: php sorting date


【解决方案1】:

正如 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"
  }
}

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

【讨论】:

    【解决方案2】:

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

    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_dates。

    【讨论】:

    • 由于某种原因获得了空值。
    • total_arr 直接以notification 为键吗?还是在notification 之前有较高的索引?
    【解决方案3】:

    如果您想使用内部数组进行排序,您最好使用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);
    

    【讨论】:

    • “水果”(posts_id_arr)不是问题,我需要对total_arr进行排序
    • 我认为他需要对整个数组进行排序,并且这可能仅适用于 for 循环之后。
    • 如果他正在尝试对整个数组进行排序。他可以使用ksort 正确排序。但是如果他试图单独对内部数组进行排序,他可以这样做array_multisort() 但建议获取输出然后按照他想要的正确顺序排序。
    【解决方案4】:

    您可以使用自定义函数通过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);
    

    【讨论】:

      【解决方案5】:

      但是,您不需要在 foreach 中执行排序。

      你可以试试下面的代码。相应地更改变量名称。

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-01-29
        • 1970-01-01
        • 2011-09-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多