Return true/false on searching multidimensional array - php

I have the following multidimensional $array:
Array
(
[0] => Array
(
[domain] => example.tld
[type] => 2
)
[1] => Array
(
[domain] => other.tld
[type] => 2
)
[2] => Array
(
[domain] => blaah.tld
[type] => 2
)
)
I simply want to recursively search all the arrays on both key and value, and return true if the key/value was found or false if nothing was found.
Expected output:
search_multi_array($array, 'domain', 'other.tld'); // Will return true
search_multi_array($array, 'type', 'other.tld'); // Will return false
search_multi_array($array, 'domain', 'google.com'); // Will return false
I've figured out a ugly-ugly method to search against the domain against all keys with this function:
function search_multi_array($search_value, $the_array) {
if (is_array($the_array)) {
foreach ($the_array as $key => $value) {
$result = search_multi_array($search_value, $value);
if (is_array($result)) {
return true;
} elseif ($result == true) {
$return[] = $key;
return $return;
}
}
return false;
} else {
if ($search_value == $the_array) {
return true;
}
else
return false;
}
}
Can anyone do better and match both against the key and value in a more elegant way?

If it doesn't go beyond those 2 levels, flipping keys/merging makes life a lot more pleasant:
<?php
$data = array
(
'0' => array
(
'domain' => 'example.tld',
'type' => 2
),
'1' => array
(
'domain' => 'other.tld',
'type' => 2,
),
'2' => array
(
'domain' => 'blaah.tld',
'type' => 2
)
);
$altered = call_user_func_array('array_merge_recursive',$data);
var_dump($altered);
var_dump(in_array('other.tld',$altered['domain']));
var_dump(in_array('other.tld',$altered['type']));
var_dump(in_array('google.com',$altered['domain']));
To go beyond 2nd level, we have to loop once through all the nodes:
$option2 = array();
foreach(new RecursiveIteratorIterator(new RecursiveArrayIterator($data)) as $key => $value){
$option2[$key][] = $value;
}
var_dump($option2);

One way is to create a reverse mapping from [domain] => [indices] and from [type] => [indices]. It's probably not going to save you much unless you do lots of searches.
(hint: you probably want to wrap it into a class to prevent inconsistencies in the mappings)
also, anytime you see something like this:
if ($search_value == $the_array) {
return true;
} else {
return false;
}
you can always turn it into:
return $search_value == $the_array;

function search_mutli_array($SearchKey, $SearchValue, $Haystack)
{
$Result = false;
if (is_array($Haystack))
{
foreach ($Haystack as $Key => $Value)
{
if (is_array($Value))
{
if (search_mutli_array($SearchKey, $SearchValue, $Value))
{
$Result = true;
break;
}
}
else if ($SearchKey == $Key && $SearchValue == $Value)
{
$Result = true;
break;
}
}
}
return $Result;
}

Related

How to I return the first of matching key values?

I have an array that I want to search for a particular value, and then return the key. However, it's likely that there will be multiple matching values. What is the best way to return the key from the first matching value?
$agent_titles = array(
'agent_1' => sales,
'agent_2' => manager, // The key I want to return
'agent_3' => manager,
'agent_4' => director;
);
if (false !== $key = array_search('manager', $agent_titles)) {
return $key;
} else {
return;
}
In this scenario I would want to return 'agent_2'. Thanks in advance!
usage of array_search was best solution
but try write your code simple as possible
$agent_titles=[
'agent_1'=>'sales',
'agent_2'=>'manager',
'agent_3'=>'manager',
'agent_4'=>'director',
];
return array_search('manager',$agent_titles);
public function blahblah($search_value = 'manager') {
$agent_titles = [
'agent_1' => sales,
'agent_2' => manager,
'agent_3' => manager,
'agent_4' => director,
];
foreach($array as $key => $value){
if($value == $search_value){
return $key;
}
}
return false;
}
function getKeyByValue($input, $array) {
foreach ( $array as $key => $value ) {
if ( $input == $value ) {
return $key;
}
}
}
$agent_titles = array(
'agent_1' => 'sales',
'agent_2' => 'manager',
'agent_3' => 'manager',
'agent_4' => 'director'
);
var_dump(getKeyByValue('manager', $agent_titles));

array_filter not working for multi dimensional array

Here is the non-functional code. It does not return anything. Not quite sure what is wrong with the syntax I am using.
function findNeedle($array, $needle) {
return array_values(array_filter($array, function($arrayValue) use($needle) { return $arrayValue['lp_url'] == $needle; } ));
}
$myarray =
0 =>
array (
'lp_url' => 'http://example.com/nx/?utm_source=aa&utm_medium=referral',
'lp_term_id' => 1435949468,
'aff_term_id' => 1445295565,
'offer_term_id' => 1445295996,
),
1 =>
array (
'lp_url' => 'http://example.org/nx/?utm_source=aa&utm_medium=referral',
'lp_term_id' => 1435949468,
'aff_term_id' => 1445295559,
'offer_term_id' => 1445295989,
),
);
$needle = 'http://example.com/nx/?utm_source=aa&utm_medium=referral';
if (is_array($myarray)) {
foreach ($myarray as $value) {
if (is_array($value))
{
$x = findNeedle($value, $needle);
}
}
Extract an array of the data for the lp_url column and check for $needle:
if(in_array($needle, array_column($myarray, 'lp_url'))) {
echo "Found";
} else {
echo "Not found";
}

Searching for value in nested php arrays

I have an array like this, that could have any number of "domain" arrays. I've removed unnecessary keys in this example.
Array
(
[result] => success
[clientid] => 7
[numreturned] => 2
[domains] => Array
(
[domain] => Array
(
[0] => Array
(
[domainname] => example.net
)
[1] => Array
(
[domainname] => example.com
)
)
)
)
I need to figure out how to check this array to see if it contains a domain name.
I'm trying to do something like this:
if(arrayContains("example.com")){
$success = true;
}
I have tried a number of solutions I found on SO, but they don't appear to be working. One example I found used array_key_exists, which is kind of the opposite of what I need.
Any suggestions on how to do this?
Use this function to help you out:
<?php
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;
}
?>
This was found in one of the comments in the PHP doc about array_search().
$array = array(
"result" => "success",
"clientid" => 7,
"numreturned" => 2,
"domains" => array(
"domain" => array(
0 => array(
"domainname" => "somedomain.com",
3 => array(
"domainname" => "searchdomanin.com",
),
),
1 => array(
"domainname" => "extwam",
),
)
)
);
$succes = FALSE;
$search = 'searchdomanin.com';
array_walk_recursive($array, function($key, $value) use(&$success, &$search){
if($key === $search){
$success = TRUE;
}
},
[&$key ,&$val]);
if($success){
echo 'FOUND';
}
Works with whatever dimension array you have.
Try something like this:
$domains = $arr['domains'];
foreach($domains AS $domain)
{
foreach($domain AS $internal_arr)
{
if($internal_arr['domainname'] == 'example.net')
{
$success = true;
}
}
}

Recursive search return all keys where value is present

Currently stuck trying to get the last part working, wanting to get all array keys returned where the value exists.
Test data
$testArr = array(
'id' => '249653315914',
'title' => 'testing',
'description' => 'testing',
'usernames' => array('jake', 'liam', 'john'),
'masterNames' => array('jake'),
'data' => array(
'aliases' => array(
'jake'
)
)
);
Method
recursive_search('jake', $testArr);
function recursive_search($needle, $haystack, $child = false) {
$values = array();
foreach($haystack as $key => $value) {
$current_key = $key;
if($needle === $value OR (is_array($value) && $children = recursive_search($needle, $value, true) !== false)) {
if($child) {
if($needle == $value) {
return true;
}
echo "children: $child, current_key: $current_key ";
return $current_key;
}
echo "current_key: $current_key, key: $key <br>";
$values[] = $current_key;
}
}
if(!empty($values)) {
return $values;
}
return false;
}
Output
current_key: usernames, key: usernames
current_key: masterNames, key: masterNames
children: 1, current_key: aliases current_key: data, key: data
array (size=3)
0 => string 'usernames' (length=5)
1 => string 'masterNames' (length=8)
2 => string 'data' (length=4)
Expected
array(
'usernames',
'masterNames',
'data' => array('aliases')
)
I'm losing track on the $child part I think, somewhere I should be returning something and assigning it but I think I've looked at this to long and overlooking the obvious.
Any help is awesome.
$testArr = array(
'id' => '249653315914',
'title' => 'jake',
'description' => 'testing',
'usernames' => array('jake', 'liam', 'john'),
'masterNames' => array('jake'),
'data' => array(
'aliases' => array(
'jake'
),
'aliases2' => array('level3' => array('jake'))
)
);
function recursive_search($needle, $haystack) {
$return = array();
if (is_array($haystack))
foreach($haystack as $key => $value)
{
if (is_array($value))
{
$child = recursive_search($needle, $value);
if (is_array($child) && !empty($child))
$return = array_merge($return, array($key => $child));
elseif ($child) $return[] = $key;
}
elseif ($value === $needle)
if (is_integer($key))
return true;
else
$return[] = $key;
}
elseif ($haystack === $needle)
return true;
return $return;
}
Output
Array
(
[0] => title
[1] => usernames
[2] => masterNames
[data] => Array
(
[0] => aliases
[aliases2] => Array
(
[0] => level3
)
)
)
Testing is needed, no warranty that it will work in all cases. Also, in the cases like this array('level3' => array('jake'), 'jake'), it will not go deeper to level3 and so on, as 'jake' is present in the original array. Please mention if that is not a desired behavior.
Edit by Bankzilla: To work with objects
function recursive_search($needle, $haystack) {
$return = array();
if (is_array($haystack) || is_object($haystack)) {
foreach($haystack as $key => $value) {
if (is_array($value) || is_object($value)) {
$child = recursive_search($needle, $value);
if ((is_array($child) || is_object($child)) && !empty($child)) {
$return = array_merge($return, array($key => $child));
} elseif ($child) {
$return[] = $key;
}
}
elseif ($value === $needle) {
if (is_integer($key)) {
return true;
} else {
$return[] = $key;
}
}
}
} elseif ($haystack === $needle) {
return true;
}
return $return;
}
the things I thought you did wrong was checking for if current $value is an array and doing a recursive search on it, while doing nothing with the return value of it (which should be the array either false ) , here I used a more step by step approach (well at least I thought so )
this works for a "tree with more branches"
EDIT
function recursive_search($needle, $haystack) {
$values = array();
foreach($haystack as $key => $value) {
if(is_array($value)) {
$children = $this->recursive_search($needle, $value);
if($children !== false){
if(!is_bool($children) and !empty($children)){
$key = array($key => $children);
}
$values[] = $key;
}
} else if(strcmp($needle, $value) == 0 ){
if(is_int($key))
return true;
else
$vaues[] = $key;
}
}
if(!empty($values)) {
return $values;
}
return false;
}
got rid of the "0"s in the array, thx Cheery for the hint (from his response)

Check if all values of keys of multidimentionnal array are numeric?

i'm gona crazy, debuting in php..
I need to check if key value of an multidimentionnal array are all numeric..
a print_r() of my $values_arr give that:
Array ( [coco] => Array ( [0] => 18 [1] => 99 ) [chanel] => 150
I need to check if 18 and 99 and 150 are numeric, i will don't know what will in the array , and this array will not more 2 dimention.
I tryed many things, the last one..:
foreach ( $values_arr as $foo=>$bar ) {
if( !in_array( $foo, $_fields_arr ) || !is_numeric($bar ) ) {
echo "NOTGOOD";
}
}
****UPDATE****
new test :Here because chanel isnot int , this exemple should be echo "not goud",
but its not the case..
$_fields_arr = array('coco','chanel','other');
$ary = array(
'coco' => array(18, 99),
'chanel' => 'yu'
);
function allIntValues($o)
{
if (is_int($o)) return true;
if (is_array($o)){
foreach ($o as $k => $v) {
if (!is_int($v)) return false;
}
}
return true;
}
foreach ($ary as $k => $v) {
if (!in_array($k, $_fields_arr) || !#allIntValues($v)){
echo "notgood";
}
else echo "good";
}
thanks for any help,
regards
Update:
$ary = Array(
'coco' => array(18, 99),
'chanel' => 150
);
$_fields_arr = array('coco', 'chanel');
function allIntValues($o)
{
if (is_int($o)) return true;
if (is_array($o)){
foreach ($o as $k => $v) {
if (!is_int($v)) return false;
}
}
return true;
}
foreach ($ary as $k => $v) {
if (in_array($k, $_fields_arr) && #allIntValues($v)){
// $ary[$k] is no good
}
}
Assuming you want to test if all values are numeric (despite how deep the value's nested):
function is_numeric_array($ary)
{
foreach ($ary as $k => $v)
{
if (is_array($v))
{
if (!is_numeric_array($v))
return false;
}
else if (!is_numeric($v))
return false;
}
return true;
}
That will (recursively) check the array and make sure every value is numeric within the array.
array(1,2,3) // true
array('foo','bar','baz') // false ('foo', 'bar' & 'baz')
array(1,2,array(3,4)) // true
array(array(1,'foo'),2,3) // false (foo)
array("1,", "2.0", "+0123.45e6") // true
You are using the value instead of the key:
if( !in_array( $bar, $_fields_arr ) || !is_numeric($foo ) ) {

Categories