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)
Related
I have an array being created which contains a date:
$arr = array();
$arr["one"][] = array(
'due' => '17-01-2021 10:00:00',
);
$arr["one"][] = array(
'due' => '17-01-2021 09:00:00',
);
$arr["two"][] = array(
'due' => '19-01-2021 09:00:00',
);
$arr["two"][] = array(
'due' => '18-01-2021 09:00:00',
);
And I want to order by the value of the 'due' key
I tried adding this uasort function:
uasort($arr, function ($a, $b) {
return $a["due"] <=> $b["due"];
});
print_r($arr);
But that still shows in the order above, whereas it should be showing the '09:00:00' value first
Your approach wasn't really that far off, I basically just changed a few little things:
Loop over each "word-number-indexed" array individually (those indexed under one and two in the main array $arr).
Convert the due dates/times to unix timestamps to have an integer that can be compared. Without this, PHP tries to sort the strings on a character-by-character basis which does not work with your format but would work if your format was YYYY-MM-DD hh:mm:ss (because the "biggest" position value would be at the start).
Use usort instead of uasort since there is no point in keeping the keys (which are integers to begin with and neither one nor due in this context.
$arr = array();
$arr["one"][] = array(
'due' => '17-01-2021 10:00:00',
);
$arr["one"][] = array(
'due' => '17-01-2021 09:00:00',
);
$arr["two"][] = array(
'due' => '19-01-2021 09:00:00',
);
$arr["two"][] = array(
'due' => '18-01-2021 09:00:00',
);
foreach ($arr as &$numberIndex) {
usort($numberIndex, function ($a, $b) {
return strtotime($a["due"]) <=> strtotime($b["due"]);
});
}
print_r($arr);
Some side notes:
Note the & at &$numberIndex, without this PHP works on an in-place copy of your value and it is never changed in $arr.
This approach with strototime() only works if all your dates/times are after epoch time 0 (which is 1st of January 1970). If you need to use older dates you can create DateTime() objects within the sort callback.
The resulting array looks like this:
Array
(
[one] => Array
(
[0] => Array
(
[due] => 17-01-2021 09:00:00
)
[1] => Array
(
[due] => 17-01-2021 10:00:00
)
)
[two] => Array
(
[0] => Array
(
[due] => 18-01-2021 09:00:00
)
[1] => Array
(
[due] => 19-01-2021 09:00:00
)
)
)
I have a question. Let say I have three or more arrays:
[weekly] => Array (
[1] => Array
(
[0] => 11:00
[1] => 11:00
)
[2] => Array
(
[0] => 13:00
[1] => 16:00
)
[5] => Array
(
[0] => 08:00
[1] => 12:00
[2] => 15:00
)
...
)
I tried to use array_unique() in foreach() loop but I can't catch that the first array has duplicate value. Actually, I would like to check if one of the array in the weekly array has a duplicate value and will return an error message that one of the arrays inside the weekly array has a duplicate value.
What is the proper checking of each sub-arrays of [weekly] that the first array has a duplicate value? I'm doing this using PHP.
Your answers will be highly appreciated. Thanks
The correct way to use array_unique() is not in a foreach loop.
<?php
$input = array(4, "4", "3", 4, 3, "3");
$result = array_unique($input);
var_dump($result);
?>
Code taken from php documentation http://php.net/manual/en/function.array-unique.php
To see if there is a difference between two arrays, you can use count() after applying array_unique().
So, make a loop over a duplicate object, unique it out. Then check if the count is the same as the original within the same loop.
This can be done in a more optimised way, but this is a start.
I've researched topics similar to this but not exactly what I'm looking to do.
I have a multidimensional array like the following.
[code] => BILL
[assets] => Array
(
[en] => Array
(
[datatype] => My Assets
[data] => Array
(
[Corporate Equity] => 41
[Global Equity] => 24
[Fixed Income – Government] => 22
[Fixed Income – Corporate] => 8.1
[Other] => 3.57
)
)
)
I'd like to remove the first inner array, but preserve the values. Shift them up one level in the array so that it looks like this.
[code] => BILL
[assets] => Array
(
[datatype] => My Assets
[data] => Array
(
[Corporate Equity] => 41
[Global Equity] => 24
[Fixed Income – Government] => 22
[Fixed Income – Corporate] => 8.1
[Other] => 3.57
)
)
This is just the beginning of the array, there are other instances of the same key [en] at the same level.
I've tried unset, array_shift and others but I need to keep the contents of [en], just shift them up one level in the array.
You can use array_map which returns an array which contains all elements of the previous array after applying the function.
In this case it will simply take the array at index en and add it's contents to the new array.
http://php.net/manual/en/function.array-map.php
$arr = array('assets' => array(
'en' => array(
'datatype' => 'My Assets',
'data' => array(
'Corporate Equity' => 41,
'Global Equity' => 24,
'Fixed Income – Government' => 22,
'Fixed Income – Corporate' => 8.1,
'Other' => 3.57
)
)
));
$new_arr = array_map(function ($e) {
return $e['en'];
}, $arr);
A simple solution that assumes the key to always be en and the subkeys to always be (only) datatype and data:
$assets['datatype'] = $assets['en']['datatype'];
$assets['data'] = $assets['en']['data'];
unset( $assets['en'] );
This code could be problematic for you in the future if that array structure ever changes (it lacks extensibility), but it gets you what you want given the information you have provided.
array_shift is the opposite of array_pop. Used in stack/queue like structures for removing the fist element http://php.net/manual/en/function.array-shift.php
What you want to do is flatten the array. But if you want to keep all the other sub-arrays as you mentioned, you might look up array_merge.
I faced the same scenario after using reader to read xml file, the returned array was having inserted 0 key array in each level like the following one:
'config' =>
0 =>
'products' =>
0 =>
'media' =>
.
.
.
so I built a small function to get rid of a specific key and shift up its child's in a two dimensions array, in my case the key was 0. hopping this would help somebody also.
public function clearMaps(&$maps, $readerMaps, $omittedKey)
{
if (is_array($readerMaps)) {
foreach ($readerMaps as $key => $map) {
if ($key !== $omittedKey) {
$maps[$key] = [];
$this->clearMaps($maps[$key], $readerMaps[$key], $omittedKey);
} else {
$this->clearMaps($maps, $readerMaps[$key], $omittedKey);
}
}
} else {
$maps = $readerMaps;
}
}
// $maps: cleaned array, will start as empty array
// $readerMaps: array needs to be cleaned
// $omittedKey: array key to git rid of.
// first call is clearMaps([], $readerMaps, 0);
I am trying to edit a plugin that is fetching a multidimensional array, then breaking it out into a foreach statement and doing stuff with the resulting data.
What I am trying to do is edit the array before it gets to the foreach statement. I want to look and see if there is a key/value combination that exists, and if it does remove that entire subarray, then reform the array and pass it to a new variable.
The current variable
$arrayslides
returns several subarrays that look like something like this (I remove unimportant variables for the sake of briefness):
Array (
[0] => Array (
[slide_active] => 1
)
[1] => Array (
[slide_active] => 0
)
)
What I want to do is look and see if one of these subarrays contains the key slide_active with a value of 0. If it contains a value of zero, I want to dump the whole subarray altogether, then reform the multidimensional array back into the variable
$arrayslides
I have tried a few array functions but have not had any luck. Any suggestions?
$arrayslides = array(0 => array ( 'slide_active' => 1, 'other_data' => "Mark" ),
1 => array ( 'slide_active' => 0, 'other_data' => "ABCDE" ),
2 => array ( 'slide_active' => 1, 'other_data' => "Baker" ),
3 => array ( 'slide_active' => 0, 'other_data' => "FGHIJ" ),
);
$matches = array_filter($arrayslides, function($item) { return $item['slide_active'] == 1; } );
var_dump($matches);
PHP >= 5.3.0
I know its not so efficient but still
foreach ($arraySlides as $key => $value)
{
if(in_array('0', array_values($value))
unset($arraySlides[$key]);
}
I have an array in PHP that looks like
Array ( [123654] => Array ( [0] => 123456789123456789 [1] => 1 [2] => 06/24/2011 [3] => 06/24/2012 [4] => 12355.44 [5] => 55321.55 ) )
I know in javascript I could access the data I need by doing array[0][0], how would I go about doing this in PHP. It is the 123456789123456789 value that I'm looking at getting.
Try this
array_slice($array, 0, 1);
http://php.net/array_slice
If you don't know the exact keys, you could do something like this:
$a = array_values($my_array);
$b = array_values($a[0]);
echo $b[0];
array_values replaces the keys by simple numbers from 0 to n-1 (where n is the count of values), by that you can access your desired value with the indexes [0][0]. See more here
http://codepad.org/YXu6884R
Here you go. See above for proof. The methodology from #azat is not explicit enough and is prone to risk if the elements of the array or sub array are re-arranged or if the key value for the super array changes.
$my_array = array( 123654 => array( 0 => '123456789123456789', 1 => '1', 2 => '06/24/2011', 3 => '06/24/2012', 4 => '12355.44', 5 => '55321.55' ) );
echo $my_array['123654'][0];
Try
$first = array_shift(array_values($array));
http://php.net/manual/en/function.array-shift.php