Php filter multidimensional array - php

I have array like this:
arr=[
627=[
'lead_data'=>['name'=>'Name1', 'date'=>'2019-04-09']
],
500=[
'lead_data'=>['name'=>'Name2', 'date'=>'2018-05-07']
],
534=[
'lead_data'=>['name'=>'Name3', 'date'=>'2019-07-10']
],
100=[
'lead_data'=>['name'=>'Name4', 'date'=>'2019-05-12']
],
]
How can I filter this array where date is between 2019-05-01 and 2019-07-12.
So in result there will be elements with ids 534 and 100.
Or date is >= 2019-07-05 or date is <= 2019-01-01 ?
I know there is array_filter function, but cant understand how to use it in thus case? Please help, thanks

The simplest solution would to just iterate over your data like so:
<?php
$begin = date('Y-m-d', strtotime("2019-05-01"));
$end = date('Y-m-d', strtotime("2019-07-12"));
foreach($array as $key => $data)
{
$date = date('Y-m-d', strtotime($$data['date']));
if (($$data > $begin) && ($date < $end)){
unset($array[$key]);
}
}
var_dump($array);

Always make sure you check out official documentation on php.net because it usually have tons of examples and very thorough explanations.
In your case you can compare dates as strings (since they are in Y-m-d format and comparing them alphabetically will do the trick):
$filtered = array_filter($arr, function ($item) {
return ($item['lead_data']['date'] > '2019-05-01') && ($item['lead_data']['date'] < '2019-07-12');
});

By using array_filter(), and using the use keyword, you can supply variables into the filter - this can be the start- and end-dates for your limits.
When using array_filter(), the data will remain in the array if the return value inside the callback is true, otherwise it will be removed. So then compare the dates, and see if they are greater than $from, and less than $to.
$from = '2019-05-01';
$to = '2019-07-12';
$result = array_filter($arr, function ($v) use ($from, $to) {
return $v['lead_data']['date'] > $from && $v['lead_data']['date'] < $to;
});
print_r($result);
Live demo at https://3v4l.org/Cmt8H

Related

How to remove values from an array in Laravel

I am trying to make a really basic day booking system and need to return all dates within a range, and then remove selected dates from that range. I tried the following code but realised that will remove duplicates which is fine, but I also need that date to be removed too.
Can anyone suggest a good way of doing this?
In the below example I am just hoping to see:
2022-04-03T00:00:00.000000Z
2022-04-04T00:00:00.000000Z
2022-04-05T00:00:00.000000Z
$start_date = "2022-04-01";
$end_date = "2022-04-05";
$datesToRemove = [
'2022-04-01T00:00:00.000000Z',
'2022-04-02T00:00:00.000000Z'
];
$range = Carbon::parse($start_date)->toPeriod($end_date)->toArray();
$available = array_unique(array_merge($range, $datesToRemove));
return $available;
To compare it is necessary to have the compared values in the same format. I decide to morph the $datesToRemove to Carbon format. The you can use to nested loops and check with PHP in_array() function.
$start_date = "2022-04-01";
$end_date = "2022-04-05";
$datesToRemove = [
"2022-04-01T00:00:00.000000Z",
"2022-04-02T00:00:00.000000Z"
];
$range = \Carbon\Carbon::parse($start_date)->toPeriod($end_date)->toArray();
$datesToRemove2 = [];
foreach($datesToRemove as $r) {
$datesToRemove2[] = \Carbon\Carbon::parse($r);
}
$res = [];
foreach($datesToRemove2 as $index => $d1) {
if(in_array($d1, $range)) {
unset($range[$index]);
}
}
return $range;
output
{
"2":"2022-04-03T00:00:00.000000Z",
"3":"2022-04-04T00:00:00.000000Z",
"4":"2022-04-05T00:00:00.000000Z"
}
Means that

Sort array of time strings naturally

I need to sort an array of time strings (which are not zero padded) naturally.
Sample data:
$totlahourdat1 = ["9:30", "15:00", "13:00"];
When I try array_multisort($totlahourdat1, SORT_DESC), the data appears unchanged.
My actual code:
while($row11 = mysqli_fetch_array($hourget))
{
$totlahourdat1[] = strtotime($row11['hours']);
}
array_multisort($totlahourdat1, SORT_DESC);
foreach ($totlahourdat1 as $time) {
$totlahourdat[] = date("h:i",$time);
}
echo "<pre>";
var_dump($totlahourdat);
echo "</pre>";
Ultimately, the array data should be ordered from earliest time to latest time:
["9:30", "13:00", "15:00"]
Simply do like below:-
$time = array(0=>"9:30",1=>"15:00",2=>"13:00");
function timecompare($a,$b)
{
return strtotime($a) < strtotime($b) ? -1: 1;
}
uasort($time ,'timecompare');
print_r(array_values($time));
Output:-https://eval.in/835353
Use natsort($array) see function definition
You can use usort() to write a custom sorting function.
$times = array("9:30", "15:00", "13:00");
usort($times, function ($a, $b) {
$a = strtotime($a);
$b = strtotime($b);
if ($a == $b) {
return 0;
}
return ($a < $b) ? 1 : -1;
});
If you are using PHP7, you could use the spaceship operator to greatly reduce the size of the sorting function.
$times = array("9:30", "15:00", "13:00");
usort($times, function ($a, $b) {
return strtotime($b) <=> strtotime($a);
});
Your problem is much simpler than you think. you just forgot to use the proper order
Just Order by ASC
array_multisort($totlahourdat1, SORT_ASC);
See demo here (https://eval.in/835356)
You do not need to parse these time expressions with strtotime() or a datetime method. Just sort naturally.
Code: (Demo)
sort($totlahourdat1, SORT_NATURAL);

nearest date in php strtotime

I have several date(strtotime) in a Variable and want the first nearest date that is after the specified date(my date) with php. what do i do?
Variable:
$varD = "1481691600,1482642000,1482037200";
my date:
1481778000 => (2016-12-15)
several date(strtotime):
1481691600 => (2016-12-14)
1482642000 => (2016-12-25)
1482037200 => (2016-12-18) //result
result:
1482037200 => (2016-12-18)
$varD = "1481691600,1482037200,1482642000";
$myDate = "1481778000";
After you explode the string of timestamps ($varD), you can filter them and return the minimum value of the result. Here is one way to do that using array_filter and min.
$comp = function($x) use ($myDate) { return $x > $myDate; };
$firstDateAfterYours = min(array_filter(explode(',', $varD), $comp));
But if you already know that the timestamps in the string will be in ascending order, it will probably be faster not to convert the whole thing to an array and sort through it. You can use strtok to go through it piece by piece and just stop as soon as you get to a timestamp larger than your target.
$ts = strtok($varD, ',');
while ($ts !== false) {
$ts = strtok(',');
if ($ts > $myDate) break;
}
$firstDateAfterYours = $ts;

Keys in PHP array are not sorted numerically

I have a PHP array with keys that contain a year and week number like so:
year-week
Using the built in ksort function it's returning them like so:
ksort($array);
2011-21
2011-3
2011-44
2011-45
Is it possible to have them sorted numerically like so:
2011-3
2011-21
2011-44
2011-45
If you are using PHP >= 5.4 use ksort($array, SORT_NATURAL);
Use uksort to sort the keys, and in the callback use, strnatcmp.
uksort($array, function($a,$b){
return strnatcmp($a,$b);
});
You can use natsort
$a = array_keys($myarray);
// $a now has
// array('2011-21', '2011-3', '2011-45', '2011-44');
natsort($a);
This prints
2011-3
2011-21
2011-44
2011-45
You can then use the $a array as a reference to each element of the array that holds the data (in the example above $myarray)
You can use ksort with natural flag. (Only PHP 5.4+ supports)
ksort($array, SORT_NATURAL);
You'll get the result you want if you format them with a 2 digit week. Something more like 2011-03. See sprint_f().
I see much simpler solutions are available, but here was my initial thought:
function cmp($a, $b) {
$comp1 = explode('-', $a);
$comp2 = explode('-', $b);
$year1 = (int) $comp1[0];
$year2 = (int) $comp2[0];
$week1 = (int) $comp1[1];
$week2 = (int) $comp2[1];
if ($year1 == $year2 && $week1 == $week2) {
return 0;
} elseif ($year1 == $year2) {
return ($week1 < $week2) ? -1 : 1;
} else {
return ($year1 < $year2) ? -1 : 1;
}
}
$array = array('2011-21', '2011-3', '2011-44', '2011-45');
uasort($array, 'cmp');

php compare/match range of values

I have an array to which I need to compare data from mysql. Usually I'm doing a straight comparison so I can do an if ($array[$i]===$mysql[$i]), but I do have one instance where I need to match it against a range of numbers (ex. 18-19, 20-24, etc). I looked into preg_match & preg_grep, but they don't seem to be what I want…
I just need a true/false result from the comparison.
The part of the array I'm trying to match against looks like this:
"age"=>array(
'18-19'=>array('total'=>0,'completed'=>0),
'20-24'=>array('total'=>0,'completed'=>0),
'25-29'=>array('total'=>0,'completed'=>0),
'30-34'=>array('total'=>0,'completed'=>0),
'35-39'=>array('total'=>0,'completed'=>0),
'40-44'=>array('total'=>0,'completed'=>0),
'45-49'=>array('total'=>0,'completed'=>0),
'50-54'=>array('total'=>0,'completed'=>0),
'55-59'=>array('total'=>0,'completed'=>0)
),"race"=>array(
"White"=>array('total'=>0,'completed'=>0),
"Black"=>array('total'=>0,'completed'=>0),
"Hispanic"=>array('total'=>0,'completed'=>0),
"Asian"=>array('total'=>0,'completed'=>0),
"Pacific Islander"=>array('total'=>0,'completed'=>0),
"Multiracial"=>array('total'=>0,'completed'=>0),
"Other"=>array('total'=>0,'completed'=>0)
)
Is there a clean way to do this?
Thanks!
list($min,$max) = explode('-', $array[$i]);
if ($mysql[$i] >= $min && $mysql[$i] <= $max) ...
PHP's range() function might be useful:
foreach ($array['age'] as $ageRange => $something) {
list($start, $limit) = explode('-', $ageRange);
foreach (range($start, $limit) as $age) {
// compare
}
}

Categories