为了账号安全,请及时绑定邮箱和手机立即绑定

使用哪个 PHP 数组函数?

使用哪个 PHP 数组函数?

PHP
撒科打诨 2022-07-16 10:50:32
我对 PHP 中所有不同的数组函数感到非常困惑,我不知道在我的场景中哪个最适合使用。我有一个列出用户注册的数组和一个列出这些用户的订阅以及用户订阅日期的数组。用户可以有多个订阅,也可以根本没有。一个例子是:$users = [    ['user_id' => 1, 'sign_up_date' => '2020-01-01 00:00:00'],    ['user_id' => 2, 'sign_up_date' => '2020-01-02 00:00:00'],    ['user_id' => 3, 'sign_up_date' => '2020-01-03 00:00:00'],    ...];$subscriptions = [    ['user_id' => 1, 'subscription_category' => 'abc', 'sign_up_date' => '2020-01-01 00:01:00'],    ['user_id' => 1, 'subscription_category' => 'def', 'sign_up_date' => '2020-01-01 00:02:00'],    ['user_id' => 1, 'subscription_category' => 'ghi', 'sign_up_date' => '2020-01-02 00:03:00'],    ['user_id' => 2, 'subscription_category' => 'jkl', 'sign_up_date' => '2020-01-02 00:01:00'],    ['user_id' => 2, 'subscription_category' => 'mno', 'sign_up_date' => '2020-01-03 00:02:00'],    ...];我试图找到的是哪些用户在他们的注册日期订阅了任何类别。所以在这种情况下,我想找到以下项目的数量:$usersWhoSubscribedOnSignUpDate = [1, 2];我能做的是:$results = [];foreach ($users as $user) {    foreach ($subscriptions as $subscription) {        $signUpDate = date('Y-m-d', strtotime($user['sign_up_date']));        $subscriptionDate = date('Y-m-d', strtotime($subscription['sign_up_date']));        if ($subscription['user_id'] === $subscription['user_id'] && $signUpDate === $subscriptionDate) {            $results[] = subscription['user_id'];        }    }}$results = array_unique($results);但这在我看来不是很优雅,我相信许多 PHP 数组函数中的一个可以以某种方式简化这个过程。array_intersect似乎不合适,因为它似乎不适用于这样的多级数组。array_map似乎不合适,因为它没有比较两个数组的能力。array_uintersect_assoc似乎它可能是一个选项,但我无法理解“附加索引检查”的含义或如何对数据进行排序。我相信回调函数需要返回两个对象之间的比较,所以也许这可以按sign_up_date属性的时间戳排序?
查看完整描述

2 回答

?
慕标琳琳

TA贡献1830条经验 获得超9个赞

您可以在 的一次迭代$users和一次迭代中执行此操作$subscriptions,而不是$subscriptions在 中的每行一次迭代$users。随着行数的增加,这可能会带来显着的性能改进。


首先,构建一个由 user_id 索引的用户注册日期的关联数组,这样您就不需要在每次需要查找日期时对其进行迭代:


$userDates = [];

foreach ($users as $user) {

    $userDates[$user['user_id']] = date('Y-m-d', strtotime($user['sign_up_date']);

}

这会给你:


Array

(

    [1] => 2020-01-01

    [2] => 2020-01-02

    [3] => 2020-01-03

)

然后只需遍历订阅一次,随时查找该用户的注册日期:


foreach ($subscriptions as $subscription) {

    if (

        date('Y-m-d', strtotime($subscription['sign_up_date'])) ===

        $userDates[$subscription['user_id']]

    ) {

        ...

    }

}

或者可能是这样的:


array_unique(array_filter(

    $subscriptions,

    function ($subscription) use ($userDates) {

        return date('Y-m-d', strtotime($subscription['sign_up_date'])) ===

            $userDates[$subscription['user_id']];

    }

));


查看完整回答
反对 回复 2022-07-16
?
LEATH

TA贡献1936条经验 获得超6个赞

我要做的第一个想法是修改您的数组,以便通过键识别用户(这是前两行)。第三行将每个用户的订阅日期减少到最早,然后第四行查找注册日期和最早订阅日期匹配的地方。


foreach( $users as $u ) { $signups[$u['user_id']] = date('Y-m-d', strtotime($u['sign_up_date']) ); }

foreach( $subscriptions as $s ) { $subs[$s['user_id']][] = date('Y-m-d', strtotime($s['sign_up_date']) ); }

foreach( $subs as $key => $value ) { $subs[$key] = min( $subs[$key] ); }

$results = array_keys( array_intersect_assoc( $signups, $subs ) );


查看完整回答
反对 回复 2022-07-16
  • 2 回答
  • 0 关注
  • 93 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信