【问题标题】:How to filter array in php using array_search value less than如何使用小于的array_search值过滤php中的数组
【发布时间】:2017-11-02 13:06:35
【问题描述】:

我在 php 中有以下数组,我试图在日期上进行过滤。日期以“Ymd”格式存储在 DropDate 键中。

我想在 Dropdate

array(3) {
    [0]=>
    array(30) {
        ["Id"]=>
        int(18762)
        ["DropDate"]=>
        string(8) "20171101"
    }
    [1]=>
    array(30) {
        ["Id"]=>
        int(18760)
        ["DropDate"]=>
        string(8) "20171102"
    }
    [2]=>
    array(30) {
        ["Id"]=>
        int(18258)
        ["DropDate"]=>
        string(8) "20171102"
    }
}

我使用了以下代码,但是当我对其进行 json_encode 编码时,它会添加 [{0:"Id":18280,"...]。

$records = array_filter($bookings, function($value) {
        $todays_date = date('Ymd');
        return $value['DropDate'] < (int)$todays_date;
    });

我不确定如何针对 dropdate 字段的小于值执行 array_search。

$todays_date = date('Ymd');
    if(($key = array_search($todays_date, array_column($student,'DropDate'))) !== false) {
        unset($student[$key]);
    }

然后,当我执行 json_encode 以将其返回到我的应用程序时,我得到了奇怪的行为,例如它在每个对象的前面添加了 0 和 1。

 [{"0":{"Id":18280,"DropDate":"20171030"},"1":{"Id":18284,"DropDate":"20171101"}}]  

我的应用程序期望这个没有 0 或 1

 [{"Id":18280,"DropDate":"20171030"},{"Id":18284,"DropDate":"20171101"}]

【问题讨论】:

  • 我不确定问题出在哪里,据我所知,它为您提供了所需的记录。如果只需要日期,可以使用array_map 修改生成的结构。
  • 在你的数组中,DropDate 似乎是一个字符串,你应该在return $value['DropDate'] &lt; (int)$todays_date; 测试之前将其转换为整数,也许你的结果不一致?
  • 谢谢,我应该提到当我对过滤后的数组进行 json_encode 时,我得到 [{"0":{"Id":18280,"DropDate":"20171030"},"1": {"Id":18284,"DropDate":"20171101"}}] 我的应用程序期望的是 [{"Id":18280,"DropDate":"20171030"},"1":{"Id":18284, "DropDate":"20171101"}]
  • @snowflakes74 你预期的数组仍然有一个"1": 这是你真正想要的,还是一个错字?
  • 在json_encode之前调用$arr = array_values($arr);

标签: php arrays filter


【解决方案1】:

array_filter 是正确的选择。

注意:比较两个日期字符串与比较两个时间戳一样有效,但恕我直言,最好使用时间戳。

试试这个:

$records = array_filter($bookings, function ($row) {
    return $row['DropDate'] < date('Ymd');
});

echo json_encode($records);

输出:

[{"Id":18762,"DropDate":"20171101"}]

eval.in demo

【讨论】:

  • 使用时间戳总是更好的 IMO,但在这种特殊情况下并不真正需要:这种日期格式适用于数值比较,但它只是 需要在之前转换为 int 。在他的情况下,它可能很有用,因为它提供了按日期进行的比较,如果您使用时间戳(比较是按秒或毫秒)
  • @Kaddath 事实证明,转换为 int 实际上是完全没有必要的:eval.in/891571
  • @Kaddath 两个语句都按预期返回 false,请参阅 here
  • 我的错,我在考虑评论中写的 javascript :D 是的 PHP 在这种情况下更聪明
【解决方案2】:

我使用强大的DateTimearray_filter 提出了这个:

<?php
$bookings = [
  ['Id' => 18762, 'DropDate' => '20171101'],
  ['Id' => 18760, 'DropDate' => '20171102'],
  ['Id' => 18258, 'DropDate' => '20171102'],
];

$records = array_filter($bookings, function ($row) {
  $today = DateTime::createFromFormat('Y-m-d', date('Y-m-d'))->format('U');
  $booking_date = DateTime::createFromFormat('Ymd', $row['DropDate'])->format('U');
  return $booking_date < $today;
});

print_r($records);

这给出了:

Array
(
    [0] => Array
        (
            [Id] => 18762
            [DropDate] => 20171101
        )

)

更好地使用时间戳。希望这会有所帮助。

演示:https://eval.in/891570


关于问题末尾的 JSON 内容

$input = <<<JSON
[{"0":{"Id":18280,"DropDate":"20171030"},"1":{"Id":18284,"DropDate":"20171101"}}] 
JSON;

您可以从您的来源解码,例如:

$decoded = json_decode($input, true);
$bookings = array_values($decoded[0]);

然后使用上面的代码。

演示:https://eval.in/891591

【讨论】:

  • 谢谢你,太棒了。请参阅我更新的关于 json_encode 何时添加 0 和 1 的问题。我知道我应该在之前的问题中提到过
猜你喜欢
  • 2019-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-14
  • 2016-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多