【问题标题】:Php array_filter with custom class to filter array with timestamp带有自定义类的 PHP array_filter 过滤带有时间戳的数组
【发布时间】:2018-09-05 09:41:28
【问题描述】:

在我的网络应用程序中,我有一些数组,它返回的数组与此输出类似:

[
    0=>
        pk = "ID"
        username = "PAGE"
        full_name = "PAGE"
        is_private = false
        reel_auto_archive = "on"
        latest_reel_media = "1536080134"
        is_favorite = false
    1=>
        pk = "ID"
        username = "PAGE"
        full_name = "PAGE"
        is_private = false
        reel_auto_archive = "on"
        latest_reel_media = "1536050134"
        is_favorite = false
]

因为我想使用 array_filter 过滤带有latest_reel_media 的数组,这是时间戳低于例如1535707694

例如:

$mediaTime = 86400 * 3;
$time_limit = strtotime(date("Y-m-d H:i:s")) - $mediaTime;
$followers = array_filter($followers, [new LowerThanFilter($time_limit,'latest_reel_media'), "isLower"]); 

LowerThanFilter类:

class LowerThanFilter
{
    private $limit;
    private $latest_reel_media;
    function __construct($limit,$latest_reel_media)
    {
        $this->limit = $limit;
        $this->latest_reel_media=$latest_reel_media;
    }
    function isLower($i)
    {
        return $i <= $this->limit;
    }
}

在测试超过 100000 条记录的代码后,array_fillter 不起作用并返回所有不正确的 100000 记录

【问题讨论】:

  • 您的班级如何比较 latest_reel_media 键和 $limit 属性?
  • @AymDev 是的,你是对的,我该如何添加它来比较?
  • array_filter 将 elements 传递给过滤函数。在您的情况下,这意味着您的过滤功能在 $i 参数中获取 whole 记录。所以你需要这样的东西:return $i['latest_reel_media'] &lt;= $this-&gt;limit;

标签: php


【解决方案1】:

您必须与latest_reel_media 键进行比较。因此,使用你的类,你应该将它设置为一个属性(这样你的类是可重用的)。

class LowerThanFilter
{
    private $limit;

    // $key is an optional parameter
    function __construct($limit, ?string $key = null)
    {
        $this->limit = $limit;
        $this->key   = $key;
    }

    // Thanks @weirdan for the use of __invoke()
    function __invoke($i)
    {
        // if $key is set, compare with key
        if (!is_null($this->key)) {
            return $i->{$this->key} <= $this->limit;
        }
        return $i <= $this->limit;
    }
}

然后像这样过滤:

$followers = array_filter($followers, new LowerThanFilter($time_limit, 'latest_reel_media'));

另一种解决方案是使用带有继承的anonymous function (use ($var))(不可重复使用但值得一看):

// this can easily stand on a single line too
$followers = array_filter($followers, function($i) use ($time_limit) {
    return $i['latest_reel_media'] <= $time_limit;
});

【讨论】:

  • 我得到Cannot use object of type stdClass as array 两种解决方案的错误
  • 对于类变体,将isLower 重命名为__invoke 可能是有意义的。然后你可以传递对象,因为它本身就是一个函数:ideone.com/JYLUpl
  • «不能使用 stdClass 类型的对象作为数组» - 那么你的条目必须是对象而不是数组(你没有在问题中真正指定)。 return $i-&gt;{$this-&gt;key} &lt;= $this-&gt;limit; 应该足以修复它。
  • 我没有收到您的最后评论?我正在编辑我的答案,你的想法很棒!
  • @AymDev 数组数据是stdClass,例如$followers 的第一行是0 = {stdClass} [11] pk = "ID",我又得到错误
【解决方案2】:

只需将 isLower 函数中的 return 语句替换为此,它就可以正常工作:

return $i['latest_reel_media'] limit;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-06
    • 2018-09-29
    • 2023-04-09
    • 2012-04-24
    • 1970-01-01
    • 1970-01-01
    • 2021-06-21
    • 2017-07-27
    相关资源
    最近更新 更多