使用哪个PHP数组函数?
我对PHP中所有不同的数组函数感到非常困惑,我不知道在我的场景中使用哪一个是最好的 我有一个数组列出用户注册,还有一个数组列出用户订阅的日期。用户可以有多个订阅,也可以根本没有订阅。例如:使用哪个PHP数组函数?,php,arrays,filtering,Php,Arrays,Filtering,我对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'], ['
$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);
array_unique(array_filter(
$subscriptions,
function ($subscription) use ($userDates) {
return date('Y-m-d', strtotime($subscription['sign_up_date'])) ===
$userDates[$subscription['user_id']];
}
));
但在我看来,这并不是很优雅,我相信许多PHP数组函数中的一个可以以某种方式简化这个过程
array\u intersect
似乎不合适,因为它似乎不适合这样的多级数组
array\u map
似乎不合适,因为它无法比较两个数组
array\u uintercat\u assoc
似乎是一个选项,但我不明白“附加索引检查”是什么意思,也不知道如何对数据进行排序。我认为回调函数需要返回两个对象之间的比较,因此可能可以按注册日期属性的时间戳进行排序。您可以在一次$users
迭代和一次$subscriptions
迭代中执行此操作,而不是在$users
中每行重复一次$subscriptions
。随着行数的增加,这可能会显著提高性能
首先,构建一个用户注册日期的关联数组,该数组由用户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']]
) {
...
}
}
或者类似于:
$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);
array_unique(array_filter(
$subscriptions,
function ($subscription) use ($userDates) {
return date('Y-m-d', strtotime($subscription['sign_up_date'])) ===
$userDates[$subscription['user_id']];
}
));
我想做的第一件事是修改数组,这样用户就可以通过键来识别(这是前两行)。第三行将每个用户的订阅日期缩短为最早,然后第四行查找注册日期和最早订阅日期匹配的位置
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 ) );
如果您的数据存储在db?@u\u mulder中,也许您可以使用SQL查询。由于db中的一些不良结构以及缺乏资源或时间来重构,我们无法有效地在db中执行查找。array\u column
有第三个参数,它消除了array\u combine
的需要。啊,太好了,从未使用过。(但现在经过重构,不再每次都执行date())标记为解决方案,因为重新映射到使用用户ID作为密钥是一个很好的解决方案。