This question already has answers here:
array_key_exists is not working
(4 answers)
Closed 8 years ago.
I have a matrix¹²³ with the following structure (it's dynamic, may or may not contains those keys (or even more))
array(
"where" => array(
"data_col1": "val1",
"data_col2": "val2"
),
"like" => array(
"data_col3": "val3"
)
);
What I need to do is to find if $var_with_data_col_name exists or not.
Using array_key_exists I can check if "where" or "like" exist, but I couldn't find a way to check inside them for a specific key.
PS:
$var_with_data_col_name would be a variable with one of the following strings:
- data_col1
- data_col2
- data_col3
You can't search for array keys or values in multidimensional arrays directly. Walk through the array and search for it then.
$data_column_1_exists = false;
foreach($array as $key => $value)
{
if(array_key_exists('data_col1', $value)
&& $key == 'where' //optionally check in specific array
)
{
$data_column_1_exists = true;
}
}
You can use this -
function key_exists_level2($arr, $key){
foreach($arr as $level1arr){
if(isset($level1arr[$key])){
return true;
}
}
return false;
}
//And check with
key_exists_level2($arr, $var_with_data_col_name)
Itterate through the "main array" and use the same function for checking the keys of each "sub array"
You can use this code, which gives you the key..which has your $var_with_data_col_name .
$data = array(
"where" => array(
"data_col1" => "val1",
"data_col2" => "val2"
),
"like" => array(
"data_col3" => "val3"
)
);
$key;
$flag = false;
$data_key = 'data_col1';
foreach($data as $our_key => $array){
if(array_key_exists($data_key,$array)){
$key = $our_key;
$flag = true;
}
}
if($flag){
print_r($data[$key]);
}
I'm sure there is already a function out there, more of an exercise for myself!
function recursive_array_key_exists($needle, array $haystack) {
if (array_key_exists($needle, $haystack)) return true;
foreach($haystack as $value) {
if (is_array($value)) {
if (recursive_array_key_exists($needle, $value)) return true;
}
}
return false;
}
Just saw the comment linking to this answer: array_key_exists is not working
I guess mine is basically identical just less code!
Related
Example:
$arr = array(array("name"=>"Bob","species"=>"human","children"=>array(array("name"=>"Alice","age"=>10),array("name"=>"Jane","age"=>13)),array("name"=>"Sparky","species"=>"dog")));
print_r($arr);
array_walk_recursive($arr, function($v,$k) {
echo "key: $k\n";
});
The thing here is that I get only the last key, but I have no way to refer where I been, that is to store a particular key and change value after I left the function or change identical placed value in another identical array.
What I would have to get instead of string is an array that would have all keys leading to given value, for example [0,"children",1,"age"].
Edit:
This array is only example. I've asked if there is universal way to iterate nested array in PHP and get full location path not only last key. And I know that there is a way of doing this by creating nested loops reflecting structure of the array. But I repeat: I don't know the array structure in advance.
To solve your problem you will need recursion. The following code will do what you want, it will also find multiple paths if they exists:
$arr = array(
array(
"name"=>"Bob",
"species"=>"human",
"children"=>array(
array(
"name"=>"Alice",
"age"=>10
),
array(
"name"=>"Jane",
"age"=>13
)
),
array(
"name"=>"Sparky",
"species"=>"dog"
)
)
);
function getPaths($array, $search, &$paths, $currentPath = array()) {
foreach ($array as $key => $value) {
if (is_array($value)) {
$currentPath[] = $key;
if (true !== getPaths($value, $search, $paths, $currentPath)) {
array_pop($currentPath);
}
} else {
if ($search == $value) {
$currentPath[] = $key;
$paths[] = $currentPath;
return true;
}
}
}
}
$paths = array();
getPaths($arr, 13, $paths);
print_r($paths);
Ok I have this kind of associative array in PHP
$arr = array(
"fruit_aac" => "apple",
"fruit_2de" => "banana",
"fruit_ade" => "grapes",
"other_add" => "sugar",
"other_nut" => "coconut",
);
now what I want is to select only the elements that starts with key fruit_. How can be this possible? can I use a regex? or any PHP array functions available? Is there any workaround? Please give some examples for your solutions
$fruits = array();
foreach ($arr as $key => $value) {
if (strpos($key, 'fruit_') === 0) {
$fruits[$key] = $value;
}
}
One solution is as follows:
foreach($arr as $key => $value){
if(strpos($key, "fruit_") === 0) {
...
...
}
}
The === ensures that the string was found at position 0, since strpos can also return FALSE if string was not found.
You try it:
function filter($var) {
return strpos($var, 'fruit_') !== false;
}
$arr = array(
"fruit_aac"=>"apple",
"fruit_2de"=>"banana",
"fruit_ade"=>"grapes",
"other_add"=>"sugar",
"other_nut"=>"coconut",
);
print_r(array_flip(array_filter(array_flip($arr), 'filter')));
If you want to try regular expression then you can try code given below...
$arr = array("fruit_aac"=>"apple",
"fruit_2de"=>"banana",
"fruit_ade"=>"grapes",
"other_add"=>"sugar",
"other_nut"=>"coconut",
);
$arr2 = array();
foreach($arr AS $index=>$array){
if(preg_match("/^fruit_.*/", $index)){
$arr2[$index] = $array;
}
}
print_r($arr2);
I hope it will be helpful for you.
thanks
I have an array like this:
$_SESSION['food'] = array(
array(
"name" => "apple",
"shape" => "round",
"color" => "red"
),
array(
"name" => "banana",
"shape" => "long",
"color" => "yellow"
)
);
I want to make a statement that checks whether any particular combination of values exists within any of the second level arrays above.
So, basically:
if NAME=APPLE and COLOR=RED in FOOD // returns true
if NAME=BANANA and COLOR=GREEN in FOOD // returns false
if NAME=APPLE and SHAPE=LONG in FOOD // returns false
How would I construct the if() statements above (just one statement as an example would be sufficient)? I am really stumped here.
I suspect it has something to do with running an in_array() within a foreach(), but I am not sure of the exact syntax.
Thanks a lot for any help.
Something like:
foreach($_SESSION['food'] as $fruit) {
if($fruit['name'] == 'apple' && $fruit['color'] == 'red') {
return true;
}
}
You have to loop over all the arrays and you could use array_intersect_assoc for comparison:
function contains($haystack, $needle) {
$needle_length = count($needle);
foreach($haystack as $sub) {
if(is_array($sub)
&& count(array_intersect_assoc($needle, $sub)) === $needle_length) {
return true;
}
}
return false;
}
and call it with:
$red_apple = array('name'=>'apple','color'=>'red');
if(contains($_SESSION['food'], $red_apple)) {
// something
}
With this you can easily check for any combination of values for any array containing arrays.
function existsInArray($name, $color){
foreach($_SESSION['food'] as $foodItem){
if($foodItem['name'] ==$name && $foodItem['color'] == $color){
return true;
}
}
return false;
}
hope that helps!
This question already has answers here:
How to check if PHP array is associative or sequential?
(60 answers)
Closed 9 years ago.
How do I find out if a PHP array was built like this:
array('First', 'Second', 'Third');
Or like this:
array('first' => 'First', 'second' => 'Second', 'third' => 'Third');
???
I have these simple functions in my handy bag o' PHP tools:
function is_flat_array($ar) {
if (!is_array($ar))
return false;
$keys = array_keys($ar);
return array_keys($keys) === $keys;
}
function is_hash($ar) {
if (!is_array($ar))
return false;
$keys = array_keys($ar);
return array_keys($keys) !== $keys;
}
I've never tested its performance on large arrays. I mostly use it on arrays with 10 or fewer keys so it's not usually an issue. I suspect it will have better performance than comparing $keys to the generated range 0..count($array).
print_r($array);
There is no difference between
array('First', 'Second', 'Third');
and
array(0 => 'First', 1 => 'Second', 2 => 'Third');
The former just has implicit keys rather than you specifying them
programmatically, you can't. I suppose the only way to check in a case like yours would be to do something like:
foreach ($myarray as $key => $value) {
if ( is_numeric($key) ) {
echo "the array appears to use numeric (probably a case of the first)";
}
}
but this wouldn't detect the case where the array was built as $array = array(0 => "first", 1 => "second", etc);
function is_assoc($array) {
return (is_array($array)
&& (0 !== count(array_diff_key($array, array_keys(array_keys($array))))
|| count($array)==0)); // empty array is also associative
}
here's another
function is_assoc($array) {
if ( is_array($array) && ! empty($array) ) {
for ( $i = count($array) - 1; $i; $i-- ) {
if ( ! array_key_exists($i, $array) ) { return true; }
}
return ! array_key_exists(0, $array);
}
return false;
}
Gleefully swiped from the is_array comments on the PHP documentation site.
That's a little tricky, especially that this form array('First', 'Second', 'Third'); implicitly lets PHP generate keys values.
I guess a valid workaround would go something like:
function array_indexed( $array )
{
$last_k = -1;
foreach( $array as $k => $v )
{
if( $k != $last_k + 1 )
{
return false;
}
$last_k++;
}
return true;
}
If you have php > 5.1 and are only looking for 0-based arrays, you can shrink the code to
$stringKeys = array_diff_key($a, array_values($a));
$isZeroBased = empty($stringKeys);
I Hope this will help you
Jerome WAGNER
function isAssoc($arr)
{
return $arr !== array_values($arr);
}
Example:
$arr = array(1 => 'Foo', 5 => 'Bar', 6 => 'Foobar');
/*... do some function so $arr now equals:
array(0 => 'Foo', 1 => 'Bar', 2 => 'Foobar');
*/
Use array_values($arr). That will return a regular array of all the values (indexed numerically).
PHP docs for array_values
array_values($arr);
To add to the other answers, array_values() will not preserve string keys. If your array has a mix of string keys and numeric keys (which is probably an indication of bad design, but may happen nonetheless), you can use a function like:
function reset_numeric_keys($array = array(), $recurse = false) {
$returnArray = array();
foreach($array as $key => $value) {
if($recurse && is_array($value)) {
$value = reset_numeric_keys($value, true);
}
if(gettype($key) == 'integer') {
$returnArray[] = $value;
} else {
$returnArray[$key] = $value;
}
}
return $returnArray;
}
Not that I know of, you might have already checked functions here
but I can imagine writing a simple function myself
resetarray($oldarray)
{
for(int $i=0;$i<$oldarray.count;$i++)
$newarray.push(i,$oldarray[i])
return $newarray;
}
I am little edgy on syntax but I guess u got the idea.