比较数组值并选择特定值
Compare array values and selecting specific one
我需要一些关于以下概念的帮助。
我有一个数组:
$values = array(
array(
'logId' => 1000,
'userId' => 1111,
'dateTime' => '2021-01-04 08:10:50',
'event' => 'OUT'
),
array(
'logId' => 1001,
'userId' => 1111,
'dateTime' => '2021-01-04 08:11:50',
'event' => 'IN'
),
array(
'logId' => 1002,
'userId' => 1111,
'dateTime' => '2021-01-04 08:11:53',
'event' => 'IN'
),
array(
'logId' => 1003,
'userId' => 1111,
'dateTime' => '2021-01-04 17:10:50',
'event' => 'OUT'
),
array(
'logId' => 1004,
'userId' => 2222,
'dateTime' => '2021-01-04 08:10:50',
'event' => 'IN'
),
array(
'logId' => 1005,
'userId' => 2222,
'dateTime' => '2021-01-04 17:00:50',
'event' => 'OUT'
),
);
我想遍历它和 select 基于“dateTime”的“first IN”和“last OUT”。
所以我应该得到:
1 | 1001 | 1111 | 2021-01-04 08:11:50 | IN |
3 | 1003 | 1111 | 2021-01-04 17:10:50 | OUT |
4 | 1004 | 2222 | 2021-01-04 08:10:50 | IN |
5 | 1005 | 2222 | 2021-01-04 17:00:50 | OUT |
如何实现这一点?
感谢任何帮助。
谢谢,
此代码完全符合您的要求
<?php
$values = array(
array(
'logId' => 1000,
'userId' => 1111,
'dateTime' => '2021-01-04 08:10:50',
'event' => 'OUT'
),
array(
'logId' => 1001,
'userId' => 1111,
'dateTime' => '2021-01-04 08:11:50',
'event' => 'IN'
),
array(
'logId' => 1002,
'userId' => 1111,
'dateTime' => '2021-01-04 08:11:53',
'event' => 'IN'
),
array(
'logId' => 1003,
'userId' => 1111,
'dateTime' => '2021-01-04 17:10:50',
'event' => 'OUT'
),
array(
'logId' => 1004,
'userId' => 2222,
'dateTime' => '2021-01-04 08:10:50',
'event' => 'IN'
),
array(
'logId' => 1005,
'userId' => 2222,
'dateTime' => '2021-01-04 17:00:50',
'event' => 'OUT'
),
);
$users = [];
foreach ($values as $value) {
if (array_key_exists($value['userId'], $users)) {
if (array_key_exists($value['event'], $users[$value['userId']])) {
if ($value['event'] == 'OUT') {
if (($users[$value['userId']][$value['event']]['dateTime']) < ($value['dateTime'])) {
$users[$value['userId']][$value['event']]['dateTime'] = $value['dateTime'];
$users[$value['userId']][$value['event']]['logId'] = $value['logId'];
}
}
if ($value['event'] == 'IN') {
if (($users[$value['userId']][$value['event']]['dateTime']) > ($value['dateTime'])) {
$users[$value['userId']][$value['event']]['dateTime'] = $value['dateTime'];
$users[$value['userId']][$value['event']]['logId'] = $value['logId'];
}
}
} else {
$users[$value['userId']][$value['event']] = [
'logId' => $value['logId'],
'dateTime' => $value['dateTime'],
];
}
} else {
$users[$value['userId']][$value['event']] = [
'logId' => $value['logId'],
'dateTime' => $value['dateTime'],
];
}
}
$counter = 1;
foreach ($users as $key => $user) {
echo "$counter ";
echo $user['IN']['logId']." ";
echo $key." ";
echo $user['IN']['dateTime']." ";
echo "IN ";
echo PHP_EOL;
$counter++;
echo "$counter ";
echo $user['OUT']['logId']." ";
echo $key." ";
echo $user['OUT']['dateTime']." ";
echo "OUT ";
echo PHP_EOL;
$counter++;
}
输出
1 1001 1111 2021-01-04 08:11:50 IN
2 1003 1111 2021-01-04 17:10:50 OUT
3 1004 2222 2021-01-04 08:10:50 IN
4 1005 2222 2021-01-04 17:00:50 OUT
在这个解决方案中,我创建了用户数组,每个用户都具有这样的结构
[1111] => Array
(
[OUT] => Array
(
[logId] => 1000
[dateTime] => 2021-01-04 17:10:50
)
[IN] => Array
(
[logId] => 1001
[dateTime] => 2021-01-04 08:11:50
)
)
然后我使用 foreach 迭代数组并更新 IN
和 OUT
如果我找到更好的
有问题随时问我
我的处理方式是:
将RAW输入数组过滤到最早的in
和最新的out
。我们不需要其余的结果。
以预期的格式重新格式化该输出。
dateTime
字符串似乎是格式正确的时间戳(大概来自 mysqli 数据库)。这很好,因为这意味着我们可以将时间戳与 <
和 >
.
进行比较
解决方案
// Define the filter array
$filterArray = [];
foreach($values as $log){
// Set a reference to this userId in the new array
$user = &$filterArray[$log["userId"]];
// If nothing has been added for this person's IN/OUT yet then add it on here
if(! ($user[$log["event"]] ?? null)){
$user[$log["event"]] = $log;
}
// If the event is IN then check to see if this IN is earlier than the one already stored
if($log["event"] == "IN" && $user["IN"]["dateTime"] > $log["dateTime"]){
$user["IN"] = $log["dateTime"];
}
// If the event is OUT then check to see if this OUT is later than the one already stored
if($log["event"] == "OUT" && $user["OUT"]["dateTime"] < $log["dateTime"]){
$user["OUT"] = $log;
}
}
// Sort by userId
ksort($filterArray);
// Define the output array
$outArray = [];
// Fill the output array
foreach($filterArray as $log){
$outArray[] = $log["IN"];
$outArray[] = $log["OUT"];
}
输出
array (
0 =>
array (
'logId' => 1001,
'userId' => 1111,
'dateTime' => '2021-01-04 08:11:50',
'event' => 'IN',
),
1 =>
array (
'logId' => 1003,
'userId' => 1111,
'dateTime' => '2021-01-04 17:10:50',
'event' => 'OUT',
),
2 =>
array (
'logId' => 1004,
'userId' => 2222,
'dateTime' => '2021-01-04 08:10:50',
'event' => 'IN',
),
3 =>
array (
'logId' => 1005,
'userId' => 2222,
'dateTime' => '2021-01-04 17:00:50',
'event' => 'OUT',
),
)
无注释代码
$filterArray = [];
foreach($values as $log){
$user = &$filterArray[$log["userId"]];
if(! ($user[$log["event"]] ?? null)){
$user[$log["event"]] = $log;
}
if($log["event"] == "IN" && $user["IN"]["dateTime"] > $log["dateTime"]){
$user["IN"] = $log["dateTime"];
}
if($log["event"] == "OUT" && $user["OUT"]["dateTime"] < $log["dateTime"]){
$user["OUT"] = $log;
}
}
ksort($filterArray);
$outArray = [];
foreach($filterArray as $log){
$outArray[] = $log["IN"];
$outArray[] = $log["OUT"];
}
我需要一些关于以下概念的帮助。
我有一个数组:
$values = array(
array(
'logId' => 1000,
'userId' => 1111,
'dateTime' => '2021-01-04 08:10:50',
'event' => 'OUT'
),
array(
'logId' => 1001,
'userId' => 1111,
'dateTime' => '2021-01-04 08:11:50',
'event' => 'IN'
),
array(
'logId' => 1002,
'userId' => 1111,
'dateTime' => '2021-01-04 08:11:53',
'event' => 'IN'
),
array(
'logId' => 1003,
'userId' => 1111,
'dateTime' => '2021-01-04 17:10:50',
'event' => 'OUT'
),
array(
'logId' => 1004,
'userId' => 2222,
'dateTime' => '2021-01-04 08:10:50',
'event' => 'IN'
),
array(
'logId' => 1005,
'userId' => 2222,
'dateTime' => '2021-01-04 17:00:50',
'event' => 'OUT'
),
);
我想遍历它和 select 基于“dateTime”的“first IN”和“last OUT”。 所以我应该得到:
1 | 1001 | 1111 | 2021-01-04 08:11:50 | IN |
3 | 1003 | 1111 | 2021-01-04 17:10:50 | OUT |
4 | 1004 | 2222 | 2021-01-04 08:10:50 | IN |
5 | 1005 | 2222 | 2021-01-04 17:00:50 | OUT |
如何实现这一点? 感谢任何帮助。
谢谢,
此代码完全符合您的要求
<?php
$values = array(
array(
'logId' => 1000,
'userId' => 1111,
'dateTime' => '2021-01-04 08:10:50',
'event' => 'OUT'
),
array(
'logId' => 1001,
'userId' => 1111,
'dateTime' => '2021-01-04 08:11:50',
'event' => 'IN'
),
array(
'logId' => 1002,
'userId' => 1111,
'dateTime' => '2021-01-04 08:11:53',
'event' => 'IN'
),
array(
'logId' => 1003,
'userId' => 1111,
'dateTime' => '2021-01-04 17:10:50',
'event' => 'OUT'
),
array(
'logId' => 1004,
'userId' => 2222,
'dateTime' => '2021-01-04 08:10:50',
'event' => 'IN'
),
array(
'logId' => 1005,
'userId' => 2222,
'dateTime' => '2021-01-04 17:00:50',
'event' => 'OUT'
),
);
$users = [];
foreach ($values as $value) {
if (array_key_exists($value['userId'], $users)) {
if (array_key_exists($value['event'], $users[$value['userId']])) {
if ($value['event'] == 'OUT') {
if (($users[$value['userId']][$value['event']]['dateTime']) < ($value['dateTime'])) {
$users[$value['userId']][$value['event']]['dateTime'] = $value['dateTime'];
$users[$value['userId']][$value['event']]['logId'] = $value['logId'];
}
}
if ($value['event'] == 'IN') {
if (($users[$value['userId']][$value['event']]['dateTime']) > ($value['dateTime'])) {
$users[$value['userId']][$value['event']]['dateTime'] = $value['dateTime'];
$users[$value['userId']][$value['event']]['logId'] = $value['logId'];
}
}
} else {
$users[$value['userId']][$value['event']] = [
'logId' => $value['logId'],
'dateTime' => $value['dateTime'],
];
}
} else {
$users[$value['userId']][$value['event']] = [
'logId' => $value['logId'],
'dateTime' => $value['dateTime'],
];
}
}
$counter = 1;
foreach ($users as $key => $user) {
echo "$counter ";
echo $user['IN']['logId']." ";
echo $key." ";
echo $user['IN']['dateTime']." ";
echo "IN ";
echo PHP_EOL;
$counter++;
echo "$counter ";
echo $user['OUT']['logId']." ";
echo $key." ";
echo $user['OUT']['dateTime']." ";
echo "OUT ";
echo PHP_EOL;
$counter++;
}
输出
1 1001 1111 2021-01-04 08:11:50 IN
2 1003 1111 2021-01-04 17:10:50 OUT
3 1004 2222 2021-01-04 08:10:50 IN
4 1005 2222 2021-01-04 17:00:50 OUT
在这个解决方案中,我创建了用户数组,每个用户都具有这样的结构
[1111] => Array
(
[OUT] => Array
(
[logId] => 1000
[dateTime] => 2021-01-04 17:10:50
)
[IN] => Array
(
[logId] => 1001
[dateTime] => 2021-01-04 08:11:50
)
)
然后我使用 foreach 迭代数组并更新 IN
和 OUT
如果我找到更好的
有问题随时问我
我的处理方式是:
将RAW输入数组过滤到最早的
in
和最新的out
。我们不需要其余的结果。以预期的格式重新格式化该输出。
dateTime
字符串似乎是格式正确的时间戳(大概来自 mysqli 数据库)。这很好,因为这意味着我们可以将时间戳与 <
和 >
.
解决方案
// Define the filter array
$filterArray = [];
foreach($values as $log){
// Set a reference to this userId in the new array
$user = &$filterArray[$log["userId"]];
// If nothing has been added for this person's IN/OUT yet then add it on here
if(! ($user[$log["event"]] ?? null)){
$user[$log["event"]] = $log;
}
// If the event is IN then check to see if this IN is earlier than the one already stored
if($log["event"] == "IN" && $user["IN"]["dateTime"] > $log["dateTime"]){
$user["IN"] = $log["dateTime"];
}
// If the event is OUT then check to see if this OUT is later than the one already stored
if($log["event"] == "OUT" && $user["OUT"]["dateTime"] < $log["dateTime"]){
$user["OUT"] = $log;
}
}
// Sort by userId
ksort($filterArray);
// Define the output array
$outArray = [];
// Fill the output array
foreach($filterArray as $log){
$outArray[] = $log["IN"];
$outArray[] = $log["OUT"];
}
输出
array (
0 =>
array (
'logId' => 1001,
'userId' => 1111,
'dateTime' => '2021-01-04 08:11:50',
'event' => 'IN',
),
1 =>
array (
'logId' => 1003,
'userId' => 1111,
'dateTime' => '2021-01-04 17:10:50',
'event' => 'OUT',
),
2 =>
array (
'logId' => 1004,
'userId' => 2222,
'dateTime' => '2021-01-04 08:10:50',
'event' => 'IN',
),
3 =>
array (
'logId' => 1005,
'userId' => 2222,
'dateTime' => '2021-01-04 17:00:50',
'event' => 'OUT',
),
)
无注释代码
$filterArray = [];
foreach($values as $log){
$user = &$filterArray[$log["userId"]];
if(! ($user[$log["event"]] ?? null)){
$user[$log["event"]] = $log;
}
if($log["event"] == "IN" && $user["IN"]["dateTime"] > $log["dateTime"]){
$user["IN"] = $log["dateTime"];
}
if($log["event"] == "OUT" && $user["OUT"]["dateTime"] < $log["dateTime"]){
$user["OUT"] = $log;
}
}
ksort($filterArray);
$outArray = [];
foreach($filterArray as $log){
$outArray[] = $log["IN"];
$outArray[] = $log["OUT"];
}