Is there a built in array method in php to filter a nested associative array?
As an example:
$myArray = array(
array('key1' => ''),
array('key1' => 'value 1'),
array('key1' => 'value 2'),
);
I want to remove any with and empty value - in this example the first element.
I know array_filter would do something similar with a flat array but cant find anything apart from looping over and creating my own new array. If that is the best solution then thats ok, i can do that myself. I just didnt want to possibly overlook a built in method for this.
$myArray = array_filter($myArray, function($el){ return !empty($el['key1']); });
There are native PHP functions you can use to do this, which is a bit simpler:
remove all the keys from nested arrays that contain no value, then
remove all the empty nested arrays.
$postArr = array_map('array_filter', $postArr);
$postArr = array_filter( $postArr );
Related
I have the following array that is supposed to only be keys:
$keys = ['mod_4_key'];
and the bigger array which contains a lot of information:
$big_array = [ 'mod_4_key' => ['old' => '', 'info' => ''], 'mod_5_key' => ..]
I would like to, based on what is inside $keys generate a new array with the information from $big_array, as such, if we are to compute the "non-difference" between the arrays, the output should be:
$final_array = [ 'mod_4_key' => ['old' => '', 'info' => '']]
I achieved this using a classic foreach but I was wondering if there was no in-built way to achieve this.
You may be better off with a simple foreach() loop, but there are probably several ways of achieving this.
This uses array_flip() on the $keys, so that you end up with another associative array, then use array_intersect_key() with the big array first.
$final_array = array_intersect_key($big_array, array_flip($keys));
The question pretty much says it all.
Im trying to match the keys of one array, to the values of another in php, without the use of a loop. Thanks :)
I could create an array by naming all the keys to the value i want to match against and set the value to null and check the key intersection, but this just seems inefficient. There probably is a simpler way to it, if anyone knows :)
For example
$array1 = array('photo' => 'foo.jpeg', 'audio' => 'bar.mp3');
$array2 = array('photo', 'audio', 'video');
Im trying to get any value of $array2 to match with any of the keys of $array1
Try these methods.
<?php
$a = array_keys( array('photo' => 'foo.jpeg', 'audio' => 'bar.mp3') );
$b = array('photo', 'audio', 'video');
//This will return empty array
print_r(array_values( array_diff($a, $b) ));
//This will return array with "video".
print_r(array_values( array_diff($b, $a) ));
//This will check Double sided array so the response
// will be element missing from both arrays.
print_r(array_values(array_merge(array_diff($b, $a), array_diff($a, $b))));
I have a simple session array and I'm pushing page titles in it, as strings:
$_SESSION['sesArray'][] = $pageTitle;
and another predefined associative array with page titles and links:
$assoc=array(array('title' => 'page title', 'link' => 'page link'));
The session array gets flooded with titles so I'm taking out duplicates:
$array1 = array_unique($_SESSION['sesArray']);
My question is: how can I compare the $assoc array against $array1 to check for page titles that exist in both and eliminate them, ending up with another array that contains unique titles along with the link?
I have tried using:
$result= array_diff_key($assoc, $array1 );
But some duplicate titles are indeed removed and some are not.
Any ideas?
ETA data:
$array1= array('Museum', 'Club');
$assoc= array(array('title' => 'Museum', 'link' => 'museum.php' ),
array('title' => 'club', 'link' => 'club.php'));
You are not really doing a diff because an array of arrays is by definition going to have nothing in common with an array of scalars. What you need to do is filter $assoc based on the contents of $array1. Try this:
$array1= array('Museum','Club');
$assoc= array(array('title' => 'Museum', 'link' => 'museum.php' ),
array('title' => 'club', 'link' => 'club.php'));
$fn = function($arr) use ($array1) {
return !in_array($arr['title'], $array1);
};
$result =array_filter($assoc, $fn);
Ah, the infamous tech-interview problem ("compare 2 arrays and to find common entries").
try something along the lines of:
$ass = array_keys($assoc);
foreach($ass as $a)
{
while (isset($_SESSION['sesArray'][$a]))
{
unset($_SESSION['sesArray'][$a]);
}
}
The way PHP associates its tuple arrays allows you to avoid the ugly O(n^2) complexity of this issue.
I have an associative array of data and I have an array of keys I would like to remove from that array (while keeping the remaining keys in original order -- not that this is likely to be a constraint).
I am looking for a one liner of php to do this.
I already know how I could loop through the arrays but it seems there should be some array_map with unset or array_filter solution just outside of my grasp.
I have searched around for a bit but found nothing too concise.
To be clear this is the problem to do in one line:
//have this example associative array of data
$data = array(
'blue' => 43,
'red' => 87,
'purple' => 130,
'green' => 12,
'yellow' => 31
);
//and this array of keys to remove
$bad_keys = array(
'purple',
'yellow'
);
//some one liner here and then $data will only have the keys blue, red, green
$out =array_diff_key($data,array_flip($bad_keys));
All I did was look through the list of Array functions until I found the one I needed (_diff_key).
The solution is indeed the one provided by Niet the Dark Absol. I would like to provide another similar solution for anyone who is after similar thing, but this one uses a whitelist instead of a blacklist:
$whitelist = array( 'good_key1', 'good_key2', ... );
$output = array_intersect_key( $data, array_flip( $whitelist ) );
Which will preserve keys from $whitelist array and remove the rest.
This is a blacklisting function I created for associative arrays.
if(!function_exists('array_blacklist_assoc')){
/**
* Returns an array containing all the entries from array1 whose keys are not present in any of the other arrays when using their values as keys.
* #param array $array1 The array to compare from
* #param array $array2 The array to compare against
* #return array $array2,... More arrays to compare against
*/
function array_blacklist_assoc(Array $array1, Array $array2) {
if(func_num_args() > 2){
$args = func_get_args();
array_shift($args);
$array2 = call_user_func_array('array_merge', $args);
}
return array_diff_key($array1, array_flip($array2));
}
}
$sanitized_data = array_blacklist_assoc($data, $bad_keys);
Lets say I have an multidimensional string array:
.food = array(
'vegetable' => array(
'carrot' => 'blablue',
'potato' => 'bluebla',
'cauliflower' => 'blabla'
),
'Fruit' => array(
'apple' => 'chicken65',
'orange' => 'salsafood',
'pear' => 'lokkulakka'
)
);
is it possible to access the array by using index as numbers, instead of using the name of the key?
So for accessing chicken65 , I will type echo $food[1][0]; I don't want to use numbers as key, because its a big array and its more user-friendly if I use string as key and it will let me do for-loops on advanced level.
You can do foreach loops to achieve much the same thing as a typical for-loop.
foreach ($foods as $key => $value) {
//For the first iteration, $key will equal 'vegetable' and $value will be the array
}
$food[1][0] != $food[1]['apple'], so you cannot use numeric keys in this case.
try
$new_array = array_values($food);
however, variable can't start with .. It should start with $
you may want to try the function array_values but since you are dealing with multidemsional arrays, here is a solution posted by a php programmer
http://www.php.net/manual/en/function.array-values.php#103905
but it would be easier to use foreach instead of for.
You can use array_keys() on the array. The resulting array can be traversed via a for-loop and gives you the associative key.
I will show it to you for the first dimension:
$aTest = array('lol' => 'lolval', 'rofl' => 'roflval');
$aKeys = array_keys($aTest);
$iCnt = count($aKeys);
for($i = 0; $i < $iCnt; ++$i)
{
var_dump($aTest[$aKeys[$i]]);
}
You would need to do this for two dimensions but I would not recommend this. It is actually more obstrusive and slower than most other solutions.
I don't think there is something native to go this route.
And it does seem like you are trying to stretch array use a bit.
You should go OOP on this one.
Create a FoodFamilly object and a Food object in which you can store arrays if necessary and you'll be able to write a nice user-friendly code and add indices if needed.
OOP is almost always the answer :)