PHP Search Multidimensional Array - Not Associative - php

I am trying to write a piece of code that searches one column of 2-D array values and returns the key when it finds it. Right now I have two functions, one to find a value and return a boolean true or false and another (not working) to return the key. I would like to merge the two in the sense of preserving the recursive nature of the finding function but returning a key. I cannot think how to do both in one function, but working key finder would be much appreciated.
Thanks
function in_array_r($needle, $haystack, $strict = true) {
foreach ($haystack as $item) {
if (($strict ? $item === $needle : $item == $needle) || (is_array($item) && in_array_r($needle, $item, $strict))) {
return true;
}
}
return false;
}
function loopAndFind($array, $index, $search){
$returnArray = array();
foreach($array as $k=>$v){
if($v[$index] == $search){
$returnArray[] = $k;
}
}
return $returnArray;
}`
Sorry, I meant to add an example. For instance:
Array [0]{
[0]=hello
[1]=6
}
[1]
{
[0]=world
[1]=4
}
and I want to search the array by the [x][0] index to check each string of words for the search term. If found, it should give back the index/key in the main array like "world" returns 1

This works:
$array = array(array('hello', 6), array('world', 4));
$searchTerm = 'world';
foreach ($array as $childKey => $childArray) {
if ($childArray['0'] == $searchTerm) {
echo $childKey; //Your Result
}
}

You already have all you need in your first function. PHP does the rest:
$findings = array_map('in_array_r', $haystack);
$findings = array_filter($findings); # remove all not found
var_dump(array_keys($findings)); # the keys you look for

Related

php if condition with search in array values

i have a problem with a php if condition
i have follow variables and arrays:
<?php
$appartamenti = array("97", "98", "99", "100");
$appartamentinoloft = array("97", "98", "99");
$case = array("103", "104", "107", "108");
$casevacanze = array("109", "110", "111", "112");
$stanze = array("115", "116");
$uffici = array("113", "114");
$locali = array("117", "118");
$garage = array("119", "120");
$terreni = array("121", "122");
$cantine = array("123", "124");
$tuttenoterreni = array($appartamenti, $case, $casevacanze, $uffici, $garage, $cantine);
?>
and i have this if condition:
<?php if ( osc_item_category_id() == $terreni) { ?>
<?php echo $custom_field_value['dimensioni-terreni'] ;?> mq
<?php } else if ( osc_item_category_id() == $tuttenoterreni) { ?>
<?php echo $custom_field_value['dimensioni'] ;?> mq
<?php } else { ?>
<?php } ?>
osc_item_category_id() is a number value
but not work.
i don't understand where is problem...
$terreni is single dimensional array and $tuttenoterreni is multi dimensional array.
For a single dimensional array, use in_array() function and for multi dimesnional array, create a custom function to find values in this multi dimensional array.
I've provided you the following code, which will help you to find values in multi dimensional array. Follow in_array() and multidimensional array
function in_array_r($needle, $haystack, $strict = false) {
foreach ($haystack as $item) {
if (($strict ? $item === $needle : $item == $needle) || (is_array($item) && in_array_r($needle, $item, $strict))) {
return true;
}
}
return false;
}
Code:
<?php
function in_array_r($needle, $haystack, $strict = false) {
foreach ($haystack as $item) {
if (($strict ? $item === $needle : $item == $needle) || (is_array($item) && in_array_r($needle, $item, $strict))) {
return true;
}
}
return false;
}
if (in_array(osc_item_category_id(),$terreni)) {
echo $custom_field_value['dimensioni-terreni'] ;
} elseif(in_array_r(osc_item_category_id(), $tuttenoterreni)) {
echo $custom_field_value['dimensioni'] ;
} else {
echo "Oops.!! No results found.";
}?>
Useful Links:
in_array() - PHP Manual
in_array() and multidimensional array
You can't check "directly" this. You are trying to compare two type of variables.
An PHP array is a pointer to "multiple variables".
If I read your code correctly, probably your function osc_item_category_id returns an integer. In that case, the first if will change to:
<?php if (in_array(osc_item_category_id(), $terreni)) { ?>
You can check documentation about in_array function here: http://be2.php.net/manual/en/function.in-array.php.
The elseif, have a similar problem. You've created a multidimensional array (an array of arrays). You need to use on this place the array_merge function (check documentation here: http://be2.php.net/manual/en/function.array-merge.php), to create a unique array with all values of the another ones. Then, you can check as on the first example:
$tuttenoterreni = array_merge($appartamenti, $case, $casevacanze, $uffici, $garage, $cantine);
<?php } else if (in_array(osc_item_category_id(), $tuttenoterreni)) { ?>
if osc_item_category_id() function return no. 121,122 user this function to compare.
<?php
$in_id = osc_item_category_id();
if(in_array($in_id,$terreni)){
echo $custom_field_value['dimensioni-terreni'];
}
?>
The in_array() function searches an array for a specific value.
Note: If the search parameter is a string and the type parameter is set to TRUE, the search is case-sensitive.
Syntax:
in_array(search,array,type)
Example :
$people = array("Peter", "Joe", "Glenn", "Cleveland");
if (in_array("Glenn", $people)){
echo "Match found";
}
Use the function
bool in_array ( value , array )
this function returns true is the value is present in the array
So modify the content of if and else if condition in your code, e.g:
if(in_array(osc_item_category_id() , $terreni ))
Also what I notice in your code is that in the elseif part you are trying to compare a numerical value returned by osc_item_category_id() with the value in the 'array of array', whereas in 'if' condition you are comparing the value returned by osc_item_category_id() with value in 'array'.
If it is the fact then in elseif part you need to run a foreach loop, comparing the value returned by 'osc_item_category_id()' with each array using the above 'in_array()' method.
Hope this help out!!!

Is there a version of array_keys that works on partial matches?

I want to return all keys in a PHP array where the corresponding value contains a search element.
array_keys will work if the value matches the search term exactly, but not if the search term occurs somewhere in the value but does not match it exactly.
How can I achieve this?
A combination of array_keys() and array_filter() can achieve what you want:
$myArray = ['knitting needle', 'haystack', 'needlepoint'];
$search = 'needle';
$keys = array_keys(
array_filter(
$myArray,
function ($value) use ($search) {
return (strpos($value, $search) !== false);
}
)
);
Demo
Try this custom function:
function array_keys_partial(array $haystack, $needle) {
$keys = array();
foreach ($haystack as $key => $value) {
if (false !== stripos($value, $needle)) {
array_push($keys,$key);
}
}
if(empty($keys)){
return false;
}
else {
return $keys;
}
}
This will return the keys on partial matches, and is also case insensitive. If you want to make it case sensitive, change stripos to strpos.

How can I replace a string inside a multidimensional array?

How can I replace a string/word that's inside a multidimensional array with a new value? I don't have its key, just know the haystack and the needle.
Say I have a multidimensional array, $submenu_arr, (don't know how many dimensions).
I want to find a value inside one of these arrays and replace it with a new value.
Actually for a translation.
Like:
recursive_arr_translation('Article', $submenu_arr, 'Artigo');//"Artigo" is a Portuguese word for "Article".
I've tried this, but not working:
function in_array_r($needle, $haystack, $new_value) {
$found = false;
foreach ($haystack as $key=>$value) {
if ($value === $needle) {
$found = true;
$haystack[$key] = $new_value;
return true;
} elseif (is_array($value)) {
$found = in_array_r($needle, $haystack[$key], $new_value);
if($found) {
return true;
}
}
}
return $found;
}
in_array_r('Article', $submenu, 'Artigo');
in_array_r('Location', $submenu, 'Localização');
EDIT: Is working, but somehow, I don't get it working, I'm trying to translate a WordPress submenu word.
You can use array_walk_recursive as suggested in the comments, and pass your original array as reference, allowing us to edit it.
<?php
$a = array("Giraffe", "Monkey", "Elephant", "Snake", 5, "other" => array("apple", "orange"));
array_walk_recursive($a, function(&$a) {
if($a == "apple") {
$a = "Banana";
}
});
echo print_r($a, true);
https://eval.in/198978
So, now we have the basic logic, let's create a function with 3 parameters.
function replace_in_array($find, $replace, &$array) {
array_walk_recursive($array, function(&$array) use($find, $replace) {
if($array == $find) {
$array= $replace;
}
});
return $array;
}
$a = array("Giraffe", "Monkey", "Elephant", "Snake", 5, "other" => array("apple", "orange"));
echo print_r( replace_in_array("apple", "banana", $a), true);
https://eval.in/198989

Search for part of string in multidimentional array returned by Drupal

I'm trying to find a part of a string in a multidimentional array.
foreach ($invitees as $invitee) {
if (in_array($invitee, $result)){
echo 'YES';
} else {
echo 'NO';
}
}
the $invitees array has 2 elements:
and $result is what I get from my Drupal database using db_select()
What I'm trying to do is, if the first part from one of the emails in $invitees is in $result it should echo "YES". (the part before the "#" charather)
For example:
"test.email" is in $result, so => YES
"user.one" is not in $result, so => NO
How do i do this? How can I search for a part of a string in a multidimentional array?
Sidenote: I noticed that the array I get from Drupal ($result) has 2 "Objects" which contain a "String", and not arrays like I would expect.
For example:
$test = array('red', 'green', array('apple', 'banana'));
Difference between $result and $test:
Does this have any effect on how I should search for my string?
Because $result is an array of objects, you'll need to use a method to access the value and compare it. So, for instance you could do:
//1: create new array $results from array of objects in $result
foreach ($result as $r) {
$results[] = get_object_vars($r);
}
//2: expanded, recursive in_array function for use with multidimensional arrays
function in_array_r($needle, $haystack, $strict = false) {
foreach ($haystack as $item) {
if (($strict ? $item === $needle : $item == $needle) || (is_array($item) && in_array_r($needle, $item, $strict))) {
return true;
}
}
return false;
}
//3: check each element of the $invitees array
foreach ($invitees as $invitee) {
echo in_array_r($invitee, $results) ? "Yes" : "No";
}
Also, for some illumination, check out this answer.
You can search through the array using preg_grep, and use a wildcard for anything before and after it. If it returns a value (or values), use key to get the index of the first one. Then do a check if its greater than or equal to 0, which means it found a match :)
<?php
$array = array('test1#gdfgfdg.com', 'test2#dgdgfdg.com', 'test3#dfgfdgdfg');
$invitee = 'test2';
$result = key(preg_grep('/^.*'.$invitee.'.*/', $array));
if ($result >= 0) {
echo 'YES';
} else {
echo 'NO';
}
?>
Accepted larsAnders's answer since he pointed me in to direction of recursive functions.
This is what I ended up using (bases on his answer):
function Array_search($array, $string) {
foreach ($array as $key => $value) {
if (is_array($value)) {
Array_search($array[$key], $string);
} else {
if ($value->data == $string) {
return TRUE;
}
}
}
return FALSE;
}

Search for a key in an array, recursively

private function find($needle, $haystack) {
foreach ($haystack as $name => $file) {
if ($needle == $name) {
return $file;
} else if(is_array($file)) { //is folder
return $this->find($needle, $file); //file is the new haystack
}
}
return "did not find";
}
Hey, this method searches for a specific key in an associative array and returns the value associated with it. There's some problem with the recursion. Any clue?
Maybe it's overkill, but it's funny to use RecursiveIterators :)
UPDATE: Maybe it was overkill with old versions of PHP, but with >=5.6 (specially with 7.0) I would totally use this without doubt.
function recursiveFind(array $haystack, $needle)
{
$iterator = new RecursiveArrayIterator($haystack);
$recursive = new RecursiveIteratorIterator(
$iterator,
RecursiveIteratorIterator::SELF_FIRST
);
foreach ($recursive as $key => $value) {
if ($key === $needle) {
return $value;
}
}
}
UPDATE: Also, as of PHP 5.6, with generators you can easily iterate over all elements which pass the filter, not only the first one:
function recursiveFind(array $haystack, $needle)
{
$iterator = new RecursiveArrayIterator($haystack);
$recursive = new RecursiveIteratorIterator(
$iterator,
RecursiveIteratorIterator::SELF_FIRST
);
foreach ($recursive as $key => $value) {
if ($key === $needle) {
yield $value;
}
}
}
// Usage
foreach (recursiveFind($haystack, $needle) as $value) {
// Use `$value` here
}
function array_search_key( $needle_key, $array ) {
foreach($array AS $key=>$value){
if($key == $needle_key) return $value;
if(is_array($value)){
if( ($result = array_search_key($needle_key,$value)) !== false)
return $result;
}
}
return false;
}
this will work !
you need to stop the recursive deep search, by return false and then check it in the function.
you can find more examples of functions (like using RecursiveArrayIterator and more) in this link :
http://php.net/manual/en/function.array-search.php
The answer provided by xPheRe was extremely helpful, but didn't quite solve the problem in my implementation. There are multiple nested associative arrays in our data structure, and there may be multiple occurrences of any given key.
In order to suit our purposes, I needed to implement a holder array that was updated while traversing the entire structure, instead of returning on the first match. The real work was provided by another poster, but I wanted to say thanks and share the final step that I had to cover.
public function recursiveFind(array $array, $needle)
{
$iterator = new RecursiveArrayIterator($array);
$recursive = new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::SELF_FIRST);
$aHitList = array();
foreach ($recursive as $key => $value) {
if ($key === $needle) {
array_push($aHitList, $value);
}
}
return $aHitList;
}
try this:
array_walk_recursive(
$arrayToFindKey,
function($value, $key, $matchingKey){
return (strcasecmp($key, $matchingKey) == 0)? true : false;
}
, 'matchingKeyValue'
);
The best solution above misses the case if the key is repeated and only returns the first value, here I get all the values in an array instead:
function recursiveFind(array $array, $needle) {
$iterator = new RecursiveArrayIterator($array);
$recursive = new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::SELF_FIRST);
$return = [];
foreach ($recursive as $key => $value) {
if ($key === $needle) {
$return[] = $value;
}
}
return $return;
}
I just been through a similar issue and here's what worked for me:
function searchArrayByKey($haystack, $needle, $i = 0) {
$result = array();
foreach($haystack as $key => $value) {
if (is_array($value)) {
$nextKey = searchArrayByKey($value, $needle);
if ($nextKey) {
return $nextKey;
}
}
if (is_array($value) && array_key_exists($needle, $value)) {
$result[$i++] = $value[$needle];
}
}
if (empty($result)) {
return false;
} else {
return $result;
}
}
This is going to return an array containing the value of all the matching keys it found in the multidimensional array. I tested this with arrays dinamically generated by an e-mail API. In the case of multiple matches, you just need to create a simple foreach loop to sort the array however you want.
I noticed the main mistake I was making was using if-ifelse conditions when I should be using if-if conditions. Any questions or criticism are very welcome, cheers!
I recently came across the same issue, when dealing with Yii2 query object.
The reason your function didn't work is that the return action doesn't work here. Just pass a reference parameter to store the value, and do whatever you want afterwards.
As you can see, this is a simple PHP function doesn't rely on any library. So I think its worth to mention with all the answer listed above.
function array_search_by_key_recursive($needle, array $haystack, &$return)
{
foreach ($haystack as $k => $v) {
if (is_array($v)) {
array_search_by_key_recursive($needle, $v, $return);
} else {
if($k === $needle){
$return = $v;
}
}
}
}
array_search_by_key_recursive($needle, array $haystack, $return);
print_r($return);

Categories