Here is an array I have to work with:
array ( [0] => monday [1] => thursday [2] => saturday [3] => sunday )
I need to run an if/else statement to check if today's day is in that array.
This does not work
// Pretend today is thursdsy
$day = date('l');
$list = array ( [0] => monday [1] => thursday [2] => saturday [3] => sunday );
if ( array_key_exists($day, $list) ) {
echo "its there";
} else {
echo "not there";
}
Neither does the in_array() version. Not sure if there is a problem using the date() with either of these functions?
If I print_r the $day i get the correct value 'thusday'
Your list has the data in the values instead of the keys.. that is why array_key_exists is failing. Instead use in_array (also since your array week days represented in all lower case... you should do the same with with the supplied $day to get a match)
if (in_array(strtolower($day), $list){
// whoop there it is..
} else {
// not here.
}
Related
I have a multidimensional array structured like below. It mimics a file structure that is storing files based on ./YEAR/MONTH/DAY/FILE.
Array
(
[2019] => Array
(
[05] => Array
(
[12] => Array
(
[0] => default.md
)
)
[12] => Array
(
[22] => Array
(
[0] => default.md
)
)
)
[2020] => Array
(
[05] => Array
(
[19] => Array
(
[0] => default.md
)
)
)
)
I am trying to loop through the entire array and get the values for each specific file while also getting the associated YEAR, MONTH and DAY for that specified file.
My loop is way off as I am trying to nest multiple foreach loops inside of a for loop. The further down the rabbit hole I get, the more issues I encounter
$post_search = directoryArrayMap("content"); //function that creates the array
$year = array_keys($post_search);
for($i = 0; $i < count($post_search); $i++ ) {
echo $year[$i] . "<br>";
foreach($post_search[$year[$i]] as $month => $day ) {
echo $month[$i] . "<br>";
foreach($post_search[$key[$month[$i]]] as $day => $post_file ) {
echo $day . "<br>";
}
}
}
I am looking for the best way to iterate through a multidimensional array. Thanks. My desired output would be something like:
File A:
Year: 2020
Month: 05
Day: 12
File B:
Year: 2019
Month: 12
Day: 22
File C:
Year: 2019
Month: 05
Day: 19
The goal is to run this in conjunction with another loop that checks "is_file" and display the output.
By using a series of nested foreach with key => value iterators you can get the output you want; the key is not to output the date parts until you get to the bottom of the loops:
foreach ($post_search as $year => $months) {
foreach ($months as $month => $days) {
foreach ($days as $day => $files) {
foreach ($files as $file) {
echo "File $file:\nYear: $year\nMonth: $month\nDay: $day\n";
}
}
}
}
Output (for your sample data):
File default.md:
Year: 2019
Month: 5
Day: 12
File default.md:
Year: 2019
Month: 12
Day: 22
File default.md:
Year: 2020
Month: 5
Day: 19
Demo on 3v4l.org
Using functions to handle the confusing nested aspect should help a lot. By no means is my example a robust solution. And personally, I'd probably put the functions in a class & make it object oriented... but that's definitely not the right solution for every case.
You'll have to adapt this, but hopefully the concept is helpful.
function handleYear($year,$arrOfMonths){
echo $year;
foreach ($arrOfMonths as $month=>$arrOfDays){
handleMonth($month,$arrOfDays);
}
}
function handleMonth($month,$arrOfDays){
echo $month;
foreach ($arrOfDays as $dayOfMonth=>$listOfFiles){
handleDay($dayOfMonth,$listOfFiles);
}
}
//to get started
foreach ($data as $year=>$arrOfMonths){
echo $year;
handleYear($year, $arrOfMonths);
}
You could also modify the sub-functions to accept the parent paramaters. Like handleMonth could also take in the year, then handleYear just passes $year along.
EDIT:
After seeing your desired output... I'd suggest passing the year & month down to the handleDay function. Then handleDay could be something like:
function handleDay($day,$arrOfFiles,$year,$month) use (&$files){
foreach ($arrOfFiles as $index=>$fileName){
$file = ['year'=>$year,'month'=>$month,'day'=>$day];
$files[] = $file;
}
}
You would then need to declare $files = [] outside the function, before declaration of handleDay if I'm not mistaken.
But then you'd just have an array of files that you could work with pretty easily.
Personally, I'd probably toil away for awhile to come up with a cleaner solution (Not fond of the use statement in this case, which I might not even be using correctly). If it's in a class, then you could use $this->files instead of the use (&$files).
I have the following PHP code working to identify intersections of dates that fall on dates where we have a Full condition.
Based on this StackOverflow post :
php check multiple dates in array are within a date range
I have a working filter using a test array ($d2).
<?php
$d2 = array ('08/23/2019','08/24/2019','08/25/2019','08/26/2019','08/27/2019','08/28/2019','08/29/2019','08/30/2019','08/31/2019','09/01/2019');
$start = strtotime('08/27/2019');
$end = strtotime('08/29/2019');
foreach($d2 AS $date) {
$timestamp = strtotime($date);
if($timestamp >= $start && $timestamp <= $end) {
echo "The date $date falls on a day where we are sold out \n";
} else {
// echo "Process Reservation \n";
}
}
?>
The print_r($d2) that works looks like this:
Array
(
[0] => 08/23/2019
[1] => 08/24/2019
[2] => 08/25/2019
[3] => 08/26/2019
[4] => 08/27/2019
[5] => 08/28/2019
[6] => 08/29/2019
[7] => 08/30/2019
[8] => 08/31/2019
[9] => 09/01/2019
)
But my array which is comprised of checking existing dates, then finding which have x number of instances on a particular date. For instance, if we have 7 or more we have a full condition (sold out).
$sold_outUS = array_filter($datesUS, function($n) { return $n >= 7; });
If I print_r($sold_outUS) this array, it shows a different type of array structure:
Array
(
[08/23/2019] => 7
[08/24/2019] => 7
[08/25/2019] => 7
[08/26/2019] => 7
[08/27/2019] => 7
[08/28/2019] => 7
[08/29/2019] => 7
[08/30/2019] => 7
[08/31/2019] => 7
[09/01/2019] => 7
)
How do I change the way this array is stored so it matches the working state and what is happening that I need to learn?
Looks as though I need an independent key and value for each instance in the array. Just don’t know how to change or reset the array to be? non-multi-dimensional?
Use array_keys to get the keys of an associative array.
$sold_outUS = array_keys(array_filter($datesUS, function($n) { return $n >= 7; }));
I have a multidimensional array that looks something like this:
Array
(
[0] => Array
(
[day] => Every Sunday
[time] => 08:00
[form] => normal
)
[1] => Array
(
[day] => Every Monday
[time] => 10:30
[form] => special
)
[2] => Array
(
[day] => Every Wednesday
[time] => 17:00
[form] => normal
)
)
I'd like to check if it contains specific days. For example, I'd like to check if it contains Monday and Sunday.
Using array_search works fine for one day. E.g. if I only want to check for Sunday:
array_search('Sunday', array_column($times, 'day'));
But it returns nothing if I pass in more than one day and attempt to search for Sunday and Monday:
array_search(array('Sunday', 'Monday'), array_column($times, 'day'));
Is there another way of doing this, preferably without iterating through everything using a for loop?
Your array for times defines the key 'day' twice, so this array will not be valid.
try changing your input array to
$times = array(
'Monday',
'Sunday
);
Secondly, array_search() cannot accept an array as its first value, as it is expecting a search term please see:
http://php.net/manual/en/function.array-search.php
As array search returns the Key of the array of the found value, this is not what you need here, you could use:
http://php.net/manual/en/function.array-count-values.php
this will grab a unique list of values in your input array and return a key => value set with the value => count as a new array.
$times = array('Monday','Tuesday','Wednesday','Monday','Monday');
print_r(array_count_values($times));
should return:
array (
[Monday] => 3
[Tuesday] => 1
[Wednesday] => 1
)
UPDATE:
After op gave a multidimensional array, the solution would be
array_count_values(array_column($array, $key));
You can use;
print_r(array_count_values($times));
One issue is that the needle for array_search is explicit, unlike strpos. So Sunday will not match a value of Every Sunday, assuming that One Sunday or Every Sunday may be desired to be searched for.
Since you already know the key to search for, I suggest using array_filterwith strpos instead. Then you can simply use count($filteredTimes) to determine how many or use array_keys($filteredTimes) to retrieve the keys as it would array_search;
It will be the equivalent of using array_column and array_search or array_count_values or array_keys($array, $search).
But instead of only returning an array of keys (or single key) with 2 iterations, it will return the original array values that contain the desired criteria or be empty, with 1 iteration.
Example: https://3v4l.org/uCUMr
$filteredTimes = array_filter($times, function($v) {
return isset($v['day']) && (false !== strpos($v['day'], 'Sunday') || false !== strpos($v['day'], 'Monday'));
});
$matchingDays = count($filteredTimes);
var_export($filteredTimes);
var_dump($matchingDays);
Result
array (
0 =>
array (
'day' => 'Every Sunday',
'time' => '08:00',
'form' => 'normal',
),
1 =>
array (
'day' => 'Every Monday',
'time' => '10:30',
'form' => 'special',
),
)
int(2)
I am posting this question in continuation of my own question at this link:
print values using for loop within foreach loop
I got a very nice solution from one person and the solution is this:
foreach($officeDetails as $key=>$value){
$str = $value['days'];
$arr = explode(", ", $str);
/*Output of $arr is :
Array (
[0] => Monday
[1] => Tuesday
)
Array (
[0] => Wednesday
[1] => Thursday
[2] => Friday
)
*/
$daysArr = array("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday");
foreach($daysArr as $i => $days){
echo $arr[$i]."<br/>";
if( $daysArr[$i] == $arr[$i] ){
echo "Selected ---- ".$days."<br/>";
}else{
echo $days."<br/>";
}
}
}
Now, the problem is when I am using this
echo $arr[$i]."<br/>";
its printing all the values correctly from $arr means "Monday Tuesday Wednesday Thursday Friday" but when I am comparing two values using if condition:
if( $daysArr[$i] == $arr[$i] ){
it is not checking the second array which is:
Array (
[0] => Wednesday
[1] => Thursday
[2] => Friday
)
and showing result
Monday
Tuesday
It means the problem is occurring at if condition not at foreach loop of $daysArr. Please help me why this is happening at if loop. I am totally lost. Your suggestions will be highly appreciated.
Kind Regards.
I think your arrays have different keys/indexs.
Meaning $daysarr[1] = Tuesday but because of your definition $arr[1] = Thursday which then isn't the same. The keys need to match to make a comparision.
Possible solution:
Make $daysarr a template and $arr just a yes/no.
Means:
When Tuesday and Saturday are selected:
$daysarr:
0->Monday
1->Tuesday
2->Wednesday
3->Thursday
4->Friday
5->Saturday
$arr:
0->0
1->1
2->0
3->0
4->0
5->1
0 means not selected
1 means selected
I have an array of timestamps that I'm importing from different XML files. This is how they look like:
<field name="timestamp">2015-04-16T07:14:16Z</field>
So I have a bunch of them stored in an array named $timestamps like this:
2015-04-16T07:14:16Z
2015-04-24T14:34:50Z
2015-04-25T08:07:24Z
2015-04-30T07:48:12Z
2015-05-02T08:37:01Z
2015-05-09T10:41:45Z
2015-05-01T07:27:21Z
2015-05-07T09:41:36Z
2015-05-12T04:06:11Z
2015-05-12T05:52:52Z
2015-05-12T11:28:16Z
I am only interested in the date part, not the time. I have tried splitting the string using the split() function.
$dates = array();
for ($i=0; $i<count($timestamps); $i++){
$dates = split ("T", $timestamps[$i]);
echo $dates[$i] . "<br>";
}
From what I understand it is storing the first part (before the T) then the part after the T. How can it store only the first part of each string?
When I try this:
echo $dates[1];
it outputs the first date fine. I'm not quite sure about the rest.
Any suggestions on a better way to accomplish this?
Thanks!
You should use strtotime and date, as opposed to string splitting and/or regex. This will help if your date format ever changes.
$dates = array();
foreach ($timestamps as $timestamp) {
$d = strtotime($timestamp);
$dates[] = date('Y-m-d', $d);
}
foreach ($dates as $date) {
echo $date . '<br/>';
}
I think splitting is not better the best is get date using date function easily. Very easy code:-
<?php
$dates = array('2015-04-16T07:14:16Z','2015-04-24T14:34:50Z','2015-04-25T08:07:24Z','2015-04-30T07:48:12Z','2015-05-02T08:37:01Z'); // i hope your dates array is like this
foreach($dates as $date){
echo date('Y-m-d',strtotime($date)).'<br/>';
}
?>
Output:- http://prntscr.com/78b0x4
Note:-I didn't take your whole array. Because it's easy to see and understand what i am doing there in my code. thanks.
You can simply use preg_replace() to remove all the "time" bits in the array:
$array = Array('2015-04-16T07:14:16Z', '2015-04-24T14:34:50Z', '2015-04-25T08:07:24Z');
// Remove "T" and anything after it
$output = preg_replace('/T.*/', '', $array);
print_r($output);
Outputs:
Array
(
[0] => 2015-04-16
[1] => 2015-04-24
[2] => 2015-04-25
)
There's no reason to drag date and strotime into this, that's just extra overhead. You have an expected, regular format already.
And I would also give a warning about using date functions: you may run into trouble with the values changing after you put them through date and strtotime depending on your server's date/time(zone) settings! Since your strings do not specify the timezone offset, you won't even be able to properly convert.. you'll just have to roll with whatever your server is at or pick one yourself.
The safer way to ensure the actual value doesn't change is to just parse it as a string. Splitting at the "T" is fine. You're just having trouble with how to handle the variables. Here is an example:
// example data
$timestamps =<<<EOT
015-04-16T07:14:16Z
2015-04-24T14:34:50Z
2015-04-25T08:07:24Z
2015-04-30T07:48:12Z
2015-05-02T08:37:01Z
2015-05-09T10:41:45Z
2015-05-01T07:27:21Z
2015-05-07T09:41:36Z
2015-05-12T04:06:11Z
2015-05-12T05:52:52Z
2015-05-12T11:28:16Z
EOT;
$timestamps=explode("\n",$timestamps);
$dates = array();
for ($i=0; $i<count($timestamps); $i++){
$d = explode("T", $timestamps[$i]);
$dates[] = $d[0];
}
print_r($dates);
output:
Array
(
[0] => 015-04-16
[1] => 2015-04-24
[2] => 2015-04-25
[3] => 2015-04-30
[4] => 2015-05-02
[5] => 2015-05-09
[6] => 2015-05-01
[7] => 2015-05-07
[8] => 2015-05-12
[9] => 2015-05-12
[10] => 2015-05-12
)