I have two arrays and I want to link together when processing them.
$dat = array(
"2020-02-01",
"2020-02-05",
"2020-02-10",
"2020-02-12",
"2020-02-15"
);
$word = array(
"Attend To,Explore,Unaided,dull,bad"
);
//User input
$start = "2020-01-01";
$end = "2020-02-07";
I want the input to affect the second array too, so when the first array gets its result from first 2, then the second array too should have it from the first 2.
//Filter out dates between start and end date
$result = array_filter($dat, function($data_item) use($start, $end) {
return $data_item >= $start && $data_item <= $end;
});
and the result is
Array
(
[0] => 2020-02-01
[1] => 2020-02-05
)
I want it to be able to link $dat and $word so that the result for word too will be
Array
(
[0] => Attend To
[1] => Explore
)
I don't find functional programming to be very readable/attractive for this case. Just use a simple foreach loop and conditionally grab the words related by the shared indices.
Since the two arrays share common indices, it is unnecessary work to combine the two arrays -- just reference the indices.
Code: (Demo)
$dat = ["2020-02-01", "2020-02-05", "2020-02-10", "20-02-12", "2020-02-15"];
$word = ["Attend To,Explore,Unaided,dull,bad"];
$words = explode(',', $word[0]);
//User input
$start = "2020-01-01";
$end = "2020-02-07";
$result = [];
foreach ($dat as $index => $date) {
if ($date >= $start && $date <= $end) {
$result[] = $words[$index];
}
}
var_export($result);
Output:
array (
0 => 'Attend To',
1 => 'Explore',
)
The original keys will be maintained after array_filter, so get the entries for keys that are the same by computing the intersection. It appears that $word is a one element array with a string, so just explode it:
$word_result = array_intersect_key(explode(',', $word[0]), $result);
See a Demo.
If one of the arrays has unique values, you can combine the array and just operate on that.
$comb = array_combine(explode(',', $word[0]), $dat);
$result = array_filter($comb, function($data_item) use($start,$end) {
return $data_item >= $start && $data_item <= $end;
});
This yields:
Array
(
[Attend To] => 2020-02-01
[Explore] => 2020-02-05
)
You can use the array as is or use array_keys to get the keys as the $word array.
If it's not guaranteed to be $word[0] then you can use reset($word) or current($word).
A possible solution assuming that the arrays have the same keys (I changed it to reflect this), is to use the constant ARRAY_FILTER_USE_BOTH to array_filter, so that the key is available in the callback function.
here i fill a second array $result2 with the words while filtering the data (note that things are added in use and $result2 is passed by reference):
$dat = array("2020-02-01","2020-02-05","2020-02-10","20-02-12","2020-02-15");
$word = array("Attend To","Explore","Unaided","dull","bad");
//User input
$start = "2020-01-01";
$end = "2020-02-07";
//Filter out dates between start and end date
$result2 = [];
$result = array_filter($dat, function($data_item, $key) use($start, $end, $word, &$result2) {
if($data_item >= $start && $data_item <= $end){
$result2[$key] = $word[$key];
return true;
}
return false;
}, ARRAY_FILTER_USE_BOTH);
AbraCadaver's answer is perfect fit when only the filtering is needed, but this can be useful in case someone has to do extra operations in the filter callback..
I have the following PHP array of arrays.
$current_date = date('Y-m-d';)
$readonly_db = array(
0 => array('2018-01-01','2018-01-02','2018-01-03','2018-01-04','2018-01-05','2018-01-06','2018-01-07','2018-01-08','2018-01-09','2018-01-10','2018-01-11','2018-01-12','2018-01-13','2018-01-14'),
1 => array('2018-01-15','2018-01-16','2018-01-17','2018-01-18','2018-01-19','2018-01-20','2018-01-21','2018-01-22','2018-01-23','2018-01-24','2018-01-25','2018-01-26','2018-01-27','2018-01-28')
);
How can I search this array of arrays for the current date and return it's left-most and right-most values? Perhaps by index?
Example based on array above:
if ($current_date == '2018-01-14') {
$pay_period_start = '2018-01-01';
$pay_period_end = '2018-01-14';
}
I am currently researching arrays but array of arrays is quite challenging.
Thank you for any help.
$pay_period_start = '';
$pay_period_end = '';
$current_date = date(Y-m-d);
foreach($readonly_db as $arr){
if(in_array($current_date, $arr)){
$pay_period_start = current($arr);
$pay_period_end = end($arr);
break;
}
}
In this code you will need to run only single foreach loop.
Try this and let me know. Cheers :)
You could do this with simple loop.
$readonly_db = array(
0 => array('2018-01-01','2018-01-02','2018-01-03','2018-01-04','2018-01-05','2018-01-06','2018-01-07','2018-01-08','2018-01-09','2018-01-10','2018-01-11','2018-01-12','2018-01-13','2018-01-14'),
1 => array('2018-01-15','2018-01-16','2018-01-17','2018-01-18','2018-01-19','2018-01-20','2018-01-21','2018-01-22','2018-01-23','2018-01-24','2018-01-25','2018-01-26','2018-01-27','2018-01-28')
);
$pay_period_start = null;
$pay_period_end = null;
$current_date = date("Y-m-d");
for($i=0;$i<count($readonly_db); $i++){
$arr = $readonly_db[$i];
for($j=0;$j<count($arr);$j++){
if($arr[$j]==$current_date){
$pay_period_start = $arr[0];
$pay_period_end = $arr[(count($arr)-1)];
}
}
}
echo $pay_period_start.' '.$pay_period_end;
The following would print the first and last item of the child array if current date is found in any of the arrays.
updated
foreach($readonly_db as $dateArray) {
foreach($dataArray as $dateString) {
if ($dateString == $current_date) {
// first item and last item in the array with current date.
echo $dateArray[0] . ' ' . end($dateArray);
}
}
}
You can foreach the array and use in_array to find the date you are looking for.
Once the date is found the values you are looking for is [0] and end of array.
Foreach($readonly_db as $val){
if (in_array('2018-01-14', $val)) {
$pay_period_start = $val[0];
$pay_period_end = end($val);
}
}
https://3v4l.org/VOWQ3
In_array returns true if the value 2018-01-14 is in the current subarray. No need to loop the subarrays and check each value.
Excel Spreadsheet to generate future years.
Does require some tweaking.
Includes some pretty cool bonus features like JSON & PHP array concatenations.
These arrays are auto generated for you.
No more having to code around WEEK 53!!!
clock.logic.xlsx
Complete Functional Code for everyone to learn.
<?php
// MOUNTAIN DAYLIGHT SAVINGS TIME
date_default_timezone_set('MST7MDT');
// = PHP Default TimeZone
print 'MOUNTAIN DAYLIGHT SAVINGS TIME';
print '<p>';
// = MySQL CURRDATE() in MySQL DATETIME Format.
$php_current_date = date('Y-m-d');
// 2018 Pay Periods
$input_arr = array(
1 => array('2018-01-01','2018-01-02','2018-01-03','2018-01-04','2018-01-05','2018-01-06','2018-01-07','2018-01-08','2018-01-09','2018-01-10','2018-01-11','2018-01-12','2018-01-13','2018-01-14'),
2 => array('2018-01-15','2018-01-16','2018-01-17','2018-01-18','2018-01-19','2018-01-20','2018-01-21','2018-01-22','2018-01-23','2018-01-24','2018-01-25','2018-01-26','2018-01-27','2018-01-28'),
3 => array('2018-01-29','2018-01-30','2018-01-31','2018-02-01','2018-02-02','2018-02-03','2018-02-04','2018-02-05','2018-02-06','2018-02-07','2018-02-08','2018-02-09','2018-02-10','2018-02-11'),
4 => array('2018-02-12','2018-02-13','2018-02-14','2018-02-15','2018-02-16','2018-02-17','2018-02-18','2018-02-19','2018-02-20','2018-02-21','2018-02-22','2018-02-23','2018-02-24','2018-02-25'),
5 => array('2018-02-26','2018-02-27','2018-02-28','2018-03-01','2018-03-02','2018-03-03','2018-03-04','2018-03-05','2018-03-06','2018-03-07','2018-03-08','2018-03-09','2018-03-10','2018-03-11'),
6 => array('2018-03-12','2018-03-13','2018-03-14','2018-03-15','2018-03-16','2018-03-17','2018-03-18','2018-03-19','2018-03-20','2018-03-21','2018-03-22','2018-03-23','2018-03-24','2018-03-25'),
7 => array('2018-03-26','2018-03-27','2018-03-28','2018-03-29','2018-03-30','2018-03-31','2018-04-01','2018-04-02','2018-04-03','2018-04-04','2018-04-05','2018-04-06','2018-04-07','2018-04-08'),
8 => array('2018-04-09','2018-04-10','2018-04-11','2018-04-12','2018-04-13','2018-04-14','2018-04-15','2018-04-16','2018-04-17','2018-04-18','2018-04-19','2018-04-20','2018-04-21','2018-04-22'),
9 => array('2018-04-23','2018-04-24','2018-04-25','2018-04-26','2018-04-27','2018-04-28','2018-04-29','2018-04-30','2018-05-01','2018-05-02','2018-05-03','2018-05-04','2018-05-05','2018-05-06'),
10 => array('2018-05-07','2018-05-08','2018-05-09','2018-05-10','2018-05-11','2018-05-12','2018-05-13','2018-05-14','2018-05-15','2018-05-16','2018-05-17','2018-05-18','2018-05-19','2018-05-20'),
11 => array('2018-05-21','2018-05-22','2018-05-23','2018-05-24','2018-05-25','2018-05-26','2018-05-27','2018-05-28','2018-05-29','2018-05-30','2018-05-31','2018-06-01','2018-06-02','2018-06-03'),
12 => array('2018-06-04','2018-06-05','2018-06-06','2018-06-07','2018-06-08','2018-06-09','2018-06-10','2018-06-11','2018-06-12','2018-06-13','2018-06-14','2018-06-15','2018-06-16','2018-06-17'),
13 => array('2018-06-18','2018-06-19','2018-06-20','2018-06-21','2018-06-22','2018-06-23','2018-06-24','2018-06-25','2018-06-26','2018-06-27','2018-06-28','2018-06-29','2018-06-30','2018-07-01'),
14 => array('2018-07-02','2018-07-03','2018-07-04','2018-07-05','2018-07-06','2018-07-07','2018-07-08','2018-07-09','2018-07-10','2018-07-11','2018-07-12','2018-07-13','2018-07-14','2018-07-15'),
15 => array('2018-07-16','2018-07-17','2018-07-18','2018-07-19','2018-07-20','2018-07-21','2018-07-22','2018-07-23','2018-07-24','2018-07-25','2018-07-26','2018-07-27','2018-07-28','2018-07-29'),
16 => array('2018-07-30','2018-07-31','2018-08-01','2018-08-02','2018-08-03','2018-08-04','2018-08-05','2018-08-06','2018-08-07','2018-08-08','2018-08-09','2018-08-10','2018-08-11','2018-08-12'),
17 => array('2018-08-13','2018-08-14','2018-08-15','2018-08-16','2018-08-17','2018-08-18','2018-08-19','2018-08-20','2018-08-21','2018-08-22','2018-08-23','2018-08-24','2018-08-25','2018-08-26'),
18 => array('2018-08-27','2018-08-28','2018-08-29','2018-08-30','2018-08-31','2018-09-01','2018-09-02','2018-09-03','2018-09-04','2018-09-05','2018-09-06','2018-09-07','2018-09-08','2018-09-09'),
19 => array('2018-09-10','2018-09-11','2018-09-12','2018-09-13','2018-09-14','2018-09-15','2018-09-16','2018-09-17','2018-09-18','2018-09-19','2018-09-20','2018-09-21','2018-09-22','2018-09-23'),
20 => array('2018-09-24','2018-09-25','2018-09-26','2018-09-27','2018-09-28','2018-09-29','2018-09-30','2018-10-01','2018-10-02','2018-10-03','2018-10-04','2018-10-05','2018-10-06','2018-10-07'),
21 => array('2018-10-08','2018-10-09','2018-10-10','2018-10-11','2018-10-12','2018-10-13','2018-10-14','2018-10-15','2018-10-16','2018-10-17','2018-10-18','2018-10-19','2018-10-20','2018-10-21'),
22 => array('2018-10-22','2018-10-23','2018-10-24','2018-10-25','2018-10-26','2018-10-27','2018-10-28','2018-10-29','2018-10-30','2018-10-31','2018-11-01','2018-11-02','2018-11-03','2018-11-04'),
23 => array('2018-11-05','2018-11-06','2018-11-07','2018-11-08','2018-11-09','2018-11-10','2018-11-11','2018-11-12','2018-11-13','2018-11-14','2018-11-15','2018-11-16','2018-11-17','2018-11-18'),
24 => array('2018-11-19','2018-11-20','2018-11-21','2018-11-22','2018-11-23','2018-11-24','2018-11-25','2018-11-26','2018-11-27','2018-11-28','2018-11-29','2018-11-30','2018-12-01','2018-12-02'),
25 => array('2018-12-03','2018-12-04','2018-12-05','2018-12-06','2018-12-07','2018-12-08','2018-12-09','2018-12-10','2018-12-11','2018-12-12','2018-12-13','2018-12-14','2018-12-15','2018-12-16'),
26 => array('2018-12-17','2018-12-18','2018-12-19','2018-12-20','2018-12-21','2018-12-22','2018-12-23','2018-12-24','2018-12-25','2018-12-26','2018-12-27','2018-12-28','2018-12-29','2018-12-30')
);
$current_pay_period_start = '';
$current_pay_period_end = '';
// Search array of arrays for $php_current_date
foreach($input_arr as $arr){
// if $php_current_date is found...
if (in_array($php_current_date, $arr)) {
// get left most index
$current_pay_period_start = current($arr);
// get right most index
$current_pay_period_end = end($arr);
print 'Php Current Date: ' . $php_current_date;
print '<br>';
print 'Current Pay Period Start: ' . $current_pay_period_start;
print '<br>';
print 'Current Pay Period End: ' . $current_pay_period_end;
exit;
}
}
print 'PHP Current Date: NOT FOUND in Array of Arrays.';
print '<br>';
print 'Current Pay Period Start: NOT FOUND in Array of Arrays.';
print '<br>';
print 'Current Pay Period End: NOT FOUND in Array of Arrays.';
?>
Having two arrays of date (mm/dd/yyyy)
array(2) {
["useless_range"]=>
array(4) {
[0]=>
string(10) "08/15/2014"
[1]=>
string(10) "08/30/2014"
[2]=>
string(10) "09/10/2014"
[3]=>
string(10) "09/20/2014"
}
["range"]=>
array(2) {
[0]=>
string(10) "08/01/2014"
[1]=>
string(10) "10/31/2014"
}
}
Consider that the array range_useless is holiday, strike, or anything like this. It's sorted already.
How can I get a useful range from the given array range?
For that example, I want the range to be
'08/01/2014 to 08/14/2014 **and** 08/31/2014 to 09/09/2014 **and** 09/21/2014 to 10/31/2014'
My first solution was create an array of all dates between the ranges and then create the full string looping using in_array, but I think there might exists a better solution
Code that create all dates between all ranges
$strDateFrom = '2014/08/15';
$strDateTo = '2014/08/30';
// takes two dates formatted as YYYY-MM-DD and creates an
// inclusive array of the dates between the from and to dates.
$aryRange=array();
$iDateFrom=mktime(1,0,0,substr($strDateFrom,5,2), substr($strDateFrom,8,2),substr($strDateFrom,0,4));
$iDateTo=mktime(1,0,0,substr($strDateTo,5,2), substr($strDateTo,8,2),substr($strDateTo,0,4));
if ($iDateTo>=$iDateFrom) {
array_push($aryRange,date('Y-m-d',$iDateFrom)); // first entry
while ($iDateFrom<$iDateTo) {
$iDateFrom+=86400; // add 24 hours
array_push($aryRange,date('Y-m-d',$iDateFrom));
}
}
print_r($aryRange);
Interesting challenge :) ! So I tried something :
$myDates = array(
"useless_range" => array(
"01/08/2015",
"01/15/2015",
"09/10/2015",
"09/20/2015"
),
"range" => array(
"08/01/2015",
"10/31/2015"
)
);
// results of strotime
$dateStart = 1420066800; //01/01/2015
$dateTo = 1422658800; // 31/01/2015
$tab = $myDates['useless_range'];
$len = count($tab);
$result = array();
$previous = $dateStart;
for($i = 0; $i < $len; $i++){
$position = $tab[$i]; // we get the current element
$iPosition = strtotime($position); // strotime it
if($previous < $iPosition && $iPosition < $dateTo){ // if the useless date is in the range
if($i % 2 == 0){ //if start of range
$result[] = array("start" => date("Y-m-d", $previous + 3600*24), "end" => date("Y-m-d", $iPosition));
}
$previous = $iPosition;
}
else { // the date is out of range, we finish the result and leave the loop
$result[] = array("start" => date("Y-m-d", $previous), "end" => date("Y-m-d", $dateTo + 3600*24));
break; //end of search
}
}
print_r($result);
The output result :
Array
(
[0] => Array
(
[start] => 2015-01-01
[end] => 2015-01-08
)
[1] => Array
(
[start] => 2015-01-15
[end] => 2015-01-31
)
)
Now to create the sentence :
$sentences = array();
foreach($result as $elem){
$sentences[] = $elem['start']." to ".$elem['end'];
}
echo implode(' **and** ', $sentences);
OK, this is not very different from what you've got but it's another point of view and I'm using the strtotime() function instead of mktime() which at least looks nicer.
I'm assuming the inputs have been validated and I have ignored the corner cases such as when the start date of the desired range/period is inside the first 'useless' range, or the end date is in a 'useless' range, but this could be easily verified if necessary.
I just wanted you to share how I would go for solving this problem.
Here's my code:
<?php
$uselessRanges = [ "08/15/2014", "08/30/2014", "09/10/2014", "09/20/2014" ];
$range = [ "08/01/2014", "10/31/2014" ];
// Convert to timestamps for easier manipulation
$rangeTs = array_map( 'strtotime', $range );
$uselessRangesTs = array_map( 'strtotime', $uselessRanges );
// Let the first date be the start of the whole range
$finalResult = [ array_shift( $rangeTs ) ];
/**
* Assuming that the useless ranges array is of the following format:
* $useless = [ 'start_useless_range_1', 'end_useless_range_1', 'start_useless_range_2', 'end_useless_range_2', ... ]
*
* For each of the useless range entries we decide whether to take the previous or the next day based on the parity of the index
*/
for( $i = 0; $i < count( $uselessRangesTs); $i++ ){
// Whether we should take the previous or the next day
$diff = $i % 2 === 0 ? -86400 : 86400;
$finalResult[] = $uselessRangesTs[$i] + $diff;
}
// Finally add the end of the whole range
$finalResult[] = array_shift( $rangeTs );
foreach( $finalResult as $date ){
echo date('m/d/Y', $date) . '<br />';
}
Assuming you only need to generate a string, and the dates are already validated and in order, I wouldn't bother with date functions. Here is a quick example of how I would do it:
$dates = array(
"useless_range" => array(
"08/15/2014",
"08/30/2014",
"09/10/2014",
"09/20/2014"
),
"range" => array(
"08/01/2015",
"10/31/2015"
)
);
$str = array();
for ( $i = 0; $i < sizeof($dates['useless_range']); $i += 2 ) {
$str[] = sprintf('%s and %s', $dates['useless_range'][$i], $dates['useless_range'][$i+1]);
}
array_unshift($str, $dates['range'][0]);
$str[] = $dates['range'][1];
$str = implode(' to ',$str);
echo $str;
// 08/01/2015 to 08/15/2014 and 08/30/2014 to 09/10/2014 and 09/20/2014 to 10/31/2015
Explanations:
The general idea is to build a sentence, so I do not bother with dates or range or anything. Just imagine words that need to be pieced together. The final result needs to be :
"range0 to useless_range0 and useless_range1 to useless_range2 and useless_range3 to range1"
This can be broken down like this:
[range0] to [useless_range0 and useless_range1] to [useless_range2 and useless_range3] to [range1]
This can be achieved very easily with implode using " to " as a separator. We just need to generate the array with range0 as first element, range1 as last element, and every piece of sentence (two consecutives dates + " and ") in between. This is a simple loop + array_shift/unshift.
Note: if your dates are not validated, or if you need to check for overlap, or anything fancy like that, then you will very probably have to build an array of dates like you are doing.