php Checking if value exists in array of array - php

I have an array within an array.
$a = array ( 0 => array ( 'value' => 'America', ), 1 => array ( 'value' => 'England', ), )
How do I check if 'America' exists in the array? The America array could be any key, and there could be any number of subarrays, so a generalized solution please.
Looking on the php manual I see in_array, but that only works for the top layer. so something like in_array("America", $a) would not work.
Thanks.

A general solution would be:
function deep_in_array($needle, $haystack) {
if(in_array($needle, $haystack)) {
return true;
}
foreach($haystack as $element) {
if(is_array($element) && deep_in_array($needle, $element))
return true;
}
return false;
}
The reason why I chose to use in_array and a loop is: Before I examine deeper levels of the array structure, I make sure, that the searched value is not in the current level. This way, I hope the code to be faster than doing some kind of depth-first search method.
Of course if your array is always 2 dimensional and you only want to search in this kind of arrays, then this is faster:
function in_2d_array($needle, $haystack) {
foreach($haystack as $element) {
if(in_array($needle, $element))
return true;
}
return false;
}

PHP doesn't have a native array_search_recursive() function, but you can define one:
function array_search_recursive($needle, $haystack) {
foreach ($haystack as $value) {
if (is_array($value) && array_search_recursive($needle, $value)) return true;
else if ($value == $needle) return true;
}
return false;
}
Untested but you get the idea.

in_array("America", array_column($a, 'value'))

function search($a,$searchval){ //$a - array; $searchval - search value;
if(is_array($a)) {
foreach($a as $val){
if(is_array($val))
if(in_array($searchval,$val)) return true;
}
}
else return false;
}
search($a, 'America'); //function call

Related

How to retrieve the complete array element or index from the multi-dimensional array when its some of the key and values are known

I have an array which consists of arrays. So, now suppose I want to retrieve the sku and price whose
key value is 2=>5 and 3=>7 so it should return price=>13 and sku=>bc i.e. that array whose index is at 1 in the array.
Hi I would probably try the following (Same as Riziers comment)
foreach($array as $key => $item) {
if($item[2] == 5 && $item[3] == 7) {
// return price
return $item;
}
}
There is a function array_search, which does what you want but for simple values. You can define your own function that will take not $needle, but callable predicate:
function array_search_callback(callable $predicate, array $array)
{
foreach ($array as $key => $item) {
if ($predicate($item)) {
return $key;
}
}
return false;
}
Having this function your example can be done like this:
$key = array_search_callback(function ($item) {
return $item[2] === '5' && $item[3] === '7';
}, $array);
$result = $key === false ? null : $array[$key];
I could simply return an item from the search function. But to be consistent with the original search function, I am returning the index.
As array_search_callback takes callable as an argument you can provide any criteria you want without the need of modifying the function itself.
Here is working demo.

Recursive array searching with proper indexing

I am trying to build a function that allows me to find my way through a complex hierarchical structure.
For example, given this array:
$arr=array("name"=>"NameA","children"=>array());
$arr["children"][]=array("name"=>"NameB","size"=>"38");
$arr["children"][]=array("name"=>"NameC","children"=>array("name"=>'NameD',"children"=>array()));
I would like to find the complete key path to a given name. For example, a search for NameC would return $a=array('children',1) and NameD would return $a=array('children',1,'children'). This would allow me to retrieve NameD with $arr['children'][1]['children']['name'] or $arr[$a[0]][$a[1]][$a[2]]['name'].
I've experimented with calls to this function at each level:
function recursive_array_search($needle,$haystack) {
foreach($haystack as $key=>$value) {
$current_key=$key;
if($needle===$value OR (is_array($value) && recursive_array_search($needle,$value) !== false)) {
return $current_key;
}
}
return false;
}
But recursive_array_search('NameC') returns 'children' instead of returning 1. I've tried modifying this in multiple ways, but to no avail.
Note that I can't change the structure of the original array because I'm using this to build a JSON array that needs to have this structure.
Any help would be appreciated.
I gather path in array
function recursive_array_search($needle,$haystack) {
foreach($haystack as $key=>$value) {
// found - create array and put lower key
if($needle===$value) return(array($key));
if (is_array($value) && ($ret = recursive_array_search($needle,$value)) !== false)
// add current key as 1st item in array
{ array_unshift($ret, $key); return $ret; }
}
return false;
}
So, recursive_array_search('NameD',$arr) return:
Array (
[0] => children
[1] => 1
[2] => children
[3] => name
)

PHP: find key in nested associtive array

I have a method to check whether a key is in a nested associative array:
private function checkKeyIsInArray($dataItemName, $array) {
foreach ($array as $key=>$value) {
if ($key == $dataItemName) return true;
if (is_array($value)) {
checkKeyIsInArray($dataItemName, $value);
}
}
return false;
}
It always returns true, regardless of the keys I include or do not include. Here is my test array:
Array
(
[0] => Array ( [reset_time] => 2013-12-11 22:24:25 )
[1] => Array ( [email] => someone#example.com )
)
Please, what am I doing wrong? If I search for "reset_time" the method returns true (as I expect); when I search for "reset_expired" the method also returns true (which is incorrect).
Your method is almost works. But there is few issues.
Comparsion numeric values and strings. In first round method has 0 as key and 'email' as value. 0 == 'email' always returns true.
You should use $this when calling object member function.
You should return value of recursive function.
Your rewrited method.
class check
{
private function checkKeyIsInArray($dataItemName, $array)
{
foreach ($array as $key => $value)
{
// convert $key to string to prevent key type convertion
if ((string) $key == $dataItemName)
return true;
if (is_array($value))
// $this added
// return added
return $this->checkKeyIsInArray($dataItemName, $value);
}
return false;
}
public function myCheck($dataItemName, $array)
{
return $this->checkKeyIsInArray($dataItemName, $array);
}
}
$check = new check();
$array = array(array('reset_time' => 123, 'email' => 123));
var_dump($check->myCheck('reset_time', $array)); // true
var_dump($check->myCheck('reset_expired', $array)); // false
var_dump($check->myCheck('0', $array)); // true
I have updated your own code, there was some minor issue.please check.
function checkKeyIsInArray($dataItemName, $array) {
foreach ($array as $key=>$value) {
## here $key is int and $dataItemName is string so its alway comes true in ur case
if ("$key" == $dataItemName) {
return true;
}
else if (is_array($value)) {
$returnvalue=checkKeyIsInArray($dataItemName, $value);
## once a matching key found stop further recursive call
if($returnvalue==true){
return true;
}
}
}
return false;
}

Check if all elements of array equal to something

Have
$my_arr_1 = array ("denied","denied","denied");
$my_arr_2 = array ("denied","denied","allowed");
Need a func that would check if all elements in the array equal to something:
in_array_all("denied",$my_arr_1); // => true
in_array_all("denied",$my_arr_2); // => false
Is there a php native function like in_array_all?
If not, what would be the most elegant way to write such a func?
function in_array_all($value, $array)
{
return (reset($array) == $value && count(array_unique($array)) == 1);
}
function in_array_all($needle,$haystack){
if(empty($needle) || empty($haystack)){
return false;
}
foreach($haystack as $k=>$v){
if($v != $needle){
return false;
}
}
return true;
}
And if you wanted to get really crazy:
function in_array_all($needle,$haystack){
if(empty($needle)){
throw new InvalidArgumentException("$needle must be a non-empty string. ".gettype($needle)." given.");
}
if(empty($haystack) || !is_array($haystack)){
throw new InvalidArgumentException("$haystack must be a non-empty array. ".gettype($haystack)." given.");
}
foreach($haystack as $k=>$v){
if($v != $needle){
return false;
}
}
return true;
}
I don't know the context of your code. But what about reversing the logic? Then you are able to use PHP's native function in_array.
$my_arr_1 = array ("denied","denied","denied");
$my_arr_2 = array ("denied","denied","allowed");
!in_array("allowed", $my_arr_1); // => true
!in_array("allowed", $my_arr_2); // => false
This entirely depends on your data set of course. But given the sample data, this would work. (Also, notice the negation ! in front of each method call to produce the desired boolean result).
Another solution using array_count_values():
function in_array_all(array $haystack, $needle) {
$count_map = array_count_values($haystack);
// in your case: [ 'denied' => 2, 'allowed' => 1 ]
return isset($count_map[$needle]) && $count_map[$needle] == count($haystack);
}
Richard's solution is best but does not have one closing paren ;-) - here is fixed and abridged:
function in_array_all($needle,$haystack)
{
if( empty($needle) || empty($haystack) ) return false;
foreach($haystack as $v)
{
if($v != $needle) return false;
}
return true;
}

filter array values from a dictionary

I have an $array on php, and I'd like to know if the values are from a specific dictionary.
For example, if my dictionary is an array of values ['cat', 'dog', 'car', 'man'] I'd like to filter my $array and return false if a word into this one is not on the dictionary.
So, if $array is :
['men', 'cat'] // return false;
['man', 'cat'] // return true;
['cat', 'dogs'] // return false;
[''] // return false;
and so on...
How can I filter an array in this manner?
function checkDictionary($array,$dictionary){
foreach($array as $array_item){
if(!in_array($array_item,$dictionary)){
return false;
}
}
return true;
}
you can also do something like:
function checkDictionary($array,$dictionary){
$result = (empty(array_diff($array,$dictionary))) ? true : false;
return $result;
}
To increase performance, you should convert you "dictionary" to an associative array, where the keys are the words in the dictionary:
$dict = array_flip($dict);
Then all you have to do is to loop over the values you search for, which is O(n):
function contains($search, $dict) {
foreach($search as $word) {
if(!array_key_exists($word, $dict)) {
return false;
}
return true;
}
Reference: array_flip, array_key_exists
function doValuesExist($dictionary, $array) {
return (count(array_intersect($dictionary,$array)) == count($array));
}

Categories