Find consecutive datetime from array php - php

Sorry for my English ,I am new here and new to PHP.I have array like below,I was trying find count of consecutive date-time from for every user within 10 min,
Array
(
[0] => Array
(
[user] => A
[time] => 2018-08-01 14:12:00
)
[1] => Array
(
[user] => B
[time] => 2018-08-01 14:12:00
)
[2] => Array
(
[user] => A
[time] => 2018-08-01 14:13:00
)
[3] => Array
(
[user] => A
[time] => 2018-08-01 14:14:00
)
[4] => Array
(
[user] => A
[time] => 2018-08-01 14:15:00
)
[5] => Array
(
[user] => B
[time] => 2018-08-01 14:50:00
)
)
I was trying to find consecutive datetime count of user click within 10 min,Like user A click 4 times consecutively within 10 min and User B click only 1 time within 10 min
Array
(
[0] => Array
(
[user] => A
[count] => 4
)
[1] => Array
(
[user] => B
[count] => 1
)
)

You can use a function with your array and the $user you want to count as parameter, and then loop into the array and sum +1 for each interaction that matches your prerequisites.
Assuming your parent array is named $users, you can do the following:
function countConsecutive($users, $username)
{
$total = 0;
foreach($users as $user) {
if($user['user'] === $username && $user['time'] >= date('Y-m-d H:i:s', strtotime('-10 minutes'))) {
$total++;
}
}
return $total;
}
The return of the function will be the count of consecutive date-time from the user in the last 10 minutes.

Related

PHP Combine multiple arrays of objects and change array structure

I have multiple separate arrays of objects that are imported (JSON-encoded) from MySQL that I need to merge and change structure. I basically need the combined [time] and [day] entries to be an array of [cycle] so I can loop over them. Currently after import/decoding the array of objects structure for each MySQL query looks like this:
(query 1)
stdClass Object
(
[day] => Array
(
[0] => stdClass Object
(
[day] => 1
[time] => 60
[name] => Running
[cycle] => 1
)
[1] => stdClass Object
(
[day] => 5
[time] => 30
[name] => Running
[cycle] => 1
)
)
[id] => 15359593
)
(query 2)
stdClass Object
(
[day] => Array
(
[0] => stdClass Object
(
[day] => 1
[time] => 55
[name] => Running
[cycle] => 2
)
[1] => stdClass Object
(
[day] => 5
[time] => 15
[name] => Running
[cycle] => 2
)
)
[id] => 36848901
)
The structure that need is:
stdClass Object
(
[day] => 1
[name] => Running
[cycle] => Array
(
[0] => stdClass Object
(
[time] => 60
[cycle] => 1
[day] => 1
)
[1] => stdClass Object
(
[time] => 55
[cycle] => 2
[day] => 1
)
)
[id] => 36848901
)
stdClass Object
(
[day] => 5
[name] => Running
[cycle] => Array
(
[0] => stdClass Object
(
[time] => 30
[cycle] => 1
[day] => 5
)
[1] => stdClass Object
(
[time] => 15
[cycle] => 2
[day] => 5
)
)
[id] => 1237465
)
I need the program to then iterate over the array using foreach [day] and then [cycle] to produce something like this:
name day cycle 1 cycle 2 cycle ..
Running 1 60 55 ..
Running 5 30 15 ..
..
It can only do it on a row by row basis. I don't have (much) control over this part of the process.
I have tried changing the structure by using foreach loops and array commands like this:
$newArray[] = array( "name" => $this->name, "day" => $this->day,
array("cycle" => $this->cycle, array("time" => $this->time, "cycle" =>
$this->cycle, "day" => $this->day)));
This gives me a structure that is almost right, per entry but not combined for all.
To combine them I've tried array_merge_recursive() and various variants but no luck.
So what I think I need is to merge the arrays of objects and then change the structure to have the values of each [time] and [day] to be nested inside the [cycle] so I can loop over them.
What is the best way to do this?
It is running on PHP 7.2.
More of my attempted code:
// get {data} part of JSON-encoded field for each mysql result
for ($x = 0; $x < $this->cycleCount; $x++) {
preg_match("/{.*}/",$this->tmpString[$x]['data'],$matches);
$this->data[$x] = json_decode($matches[0]);
foreach ($this->data[$x] as $day) {
$newArray[] = array( "name" => $day->name, "day" => $day->day,
array("cycle" => $day->cycle,
array("time" => $day->time,
"cycle" => $day->cycle,
"day" => $day->day)
)
);
}
$data = array();
$object = json_decode($querObject,true);
foreach($object as $day => $info)
{
foreach($info['cycle'] as $cycleInfo)
{
$data[$info['$id']]['name'] = $cycleInfo['name'];
$data[$info['$id']]['day'] = $cycleInfo['day'];
$data[$info['$id']]['id'] = $cycleInfo['id'];
$data[$info['$id']]['cycle'][] =array('time'=>$cycleInfo['time'],'cycle'=>$cycleInfo['cycle'],'day'=>=>$cycleInfo['day']);
}
}

Remove duplicate yyyy/mm from array

How I can remove duplicate entries based on Year and Month when my date format is YYYY-MM-DD? I tried removing days, but then I need to add the last day in the array, so my approach was wrong.
My array looks like this:
Array
(
[0] => Array
(
[id] => 9240399
[time] => 2018-01-01
[pages_indexed] => 942
)
[1] => Array
(
[id] => 9240322
[time] => 2018-01-02
[pages_indexed] => 940
)
[2] => Array
(
[id] => 9240344
[time] => 2018-01-03
[pages_indexed] => 947
)
[30] => Array
(
[id] => 9240344
[time] => 2018-01-31
[pages_indexed] => 947
)
[31] => Array
(
[id] => 9240344
[time] => 2018-02-01
[pages_indexed] => 1999
)
[32] => Array
(
[id] => 9240344
[time] => 2018-02-02
[pages_indexed] => 13339
)
Notice that I skipped some entries, so my dates are 2018-01-01, 2018-01-02, etc.
Array_unique would not work here since the day is different.
I tried this: ( $entries['time'] is like ex: 2018-01-01. )
$remove = DATE("Y-m",$entries['time']);
$entriesa = array_unique($remove);
$entries['time'] = $entriesa;
Well... you could loop through your results and index each key as the Year and Month, and then update this index with the row that fits the pattern, meaning you would only have the rows you expect (but you would only have the last reference of them).
Like this:
$expectedArray = [];
foreach ($arrayDuplicated as $item) {
$indexKey = substr($item['time'], 0, 7);
$expectedArray[$indexKey] = $item;
}

How to check if a specific key and value exist more than 3 times in php array

I have following 'challange';
I have array like this:
Array
(
[0] => stdClass Object
(
[id] => 94
[day] => Monday
[date] => 2018-07-09
[week_number] => 2
)
[1] => stdClass Object
(
[id] => 95
[day] => Tuesday
[date] => 2018-07-10
[week_number] => 2
)
[2] => stdClass Object
(
[id] => 83
[day] => Saturday
[date] => 2018-07-07
[week_number] => 1
)
[3] => stdClass Object
(
[id] => 82
[day] => Friday
[date] => 2018-07-06
[week_number] => 1
)
[4] => stdClass Object
(
[id] => 81
[day] => Thursday
[date] => 2018-07-05
[week_number] => 1
)
[5] => stdClass Object
(
[id] => 80
[day] => Wednesday
[date] => 2018-07-04
[week_number] => 1
)
)
I wanted to know how many times user have selected "week_number" 1,2 and so on, I don't want to allow user to select more than 3 events in a week.
I am using fullcalendar to display events.
How can I achieve that?
Thank you in advance
In PHP 7 you can extract the week_number properties and count the values:
$result = array_count_values(array_column($array, 'week_number'));
Will yield the week_number as the key and the count as the value:
array
(
[1] => 4
[2] => 2
)
Depending upon wheteher you want to check for multiples or just one, loop and check for > 3 or use in_array(3, $result).
You might use array_reduce to
$result = array_reduce($input, function($outpu, $item) {
if(!isset($output[$item->week_number])) {
$output[$item->week_number] = 0;
}
return $output[$item->week_number]++;
});
var_dump($result);
Where $input is You array of objects
If you only need to check if there are more than x events, and you don't need to count all events, better use something like this:
function hasTooManySelections($items, $maxSelections = 3)
{
$counts = [];
foreach ($items as $item) {
$counts[$item->week_number] = isset($counts[$item->week_number]) ? $counts[$item->week_number] + 1 : 1;
if ($counts[$item->week_number] > $maxSelections) {
return true;
}
}
return false;
}
var_dump(hasTooManySelections($items));
Demo: https://3v4l.org/XbiH0
You can sort your array in respect of group by week number and then count length of all perticular group

PHP Remove subarray from main array if specific value range is found

Lets say I have the following array:
[9] => Array
(
[0] => Bob Smith
[1] => bobsmith#gmail.com
[2] => Helsinki
[3] => 10
[4] => 34
[5] => 2014-05-12
)
[10] => Array
(
[0] => John Smith
[1] => johnsmith#domain.com
[2] => some values
[3] => 9
[4] => 67
[5] => 2014-05-15
)
[11] => Array
(
[0] => Clarke Kent
[1] => ckent#superman.com
[2] => Crystal
[3] => 9
[4] => 89
[5] => 2014-05-16
)
What if i want to remove a subarray when the date falls outside a specific range. So if i say wanted to find data where the date is between 2014-05-14 and 2014-05-28. Then the (new) array would print the following:
[10] => Array
(
[0] => John Smith
[1] => johnsmith#domain.com
[2] => some values
[3] => 9
[4] => 67
[5] => 2014-05-15
)
[11] => Array
(
[0] => Clarke Kent
[1] => ckent#superman.com
[2] => Crystal
[3] => 9
[4] => 89
[5] => 2014-05-16
)
I thought something like the following:
foreach ($array as $row) {
if($row[5] >= '2014-05-14' && $row[5] <= '2014-05-14') {
// Do Something // e.g. unset subarray?
}
}
OR should i approach it differently and iterate through the array and if a subarray matches my criteria create a new array. The result being an array with subarrays that contain dates that meet my date range. I hope this makes sense, i am trying to find the most efficient way to do this.
Thanks
For the use case described, I would personally use array_filter:
$start_date = DateTime::createFromFormat('Y-m-d', '2014-05-14');
$end_date = DateTime::createFromFormat('Y-m-d', '2014-06-14');
$filtered_array = array_filter($array, function($row) use ($start_date, $end_date) {
$date = DateTime::createFromFormat('Y-m-d', $row[5]);
return $date >= $start_date && $date <= $end_date;
});

PHP Looping based on date

ok so i have this array of about 151 elements and there is a date field as one of the elements. The array is a two week range. I want to count how many elements are in the first week and how any are in the second week. Here is my example array.
[0] => Array
(
[0] => 4d50
[date] => 07-10-2010
[telephone] => something
[Sno] => 1
)
[1] => Array
(
[0] => 4g50
[date] => 07-03-2010
[telephone] => something
[Sno] => 1
)
[2] => Array
(
[0] => 4s50
[date] => 06-29-2010
[telephone] => something
[Sno] => 1
function getweek($a){
//altered code., m-d-Y is no a format strtotime likes):
return DateTime::createFromFormat('m-d-Y',$a['date'])->format('W');
}
var_dump(array_count_values(array_map('getweek',$inputarray)));

Categories