PHP: Find index of specific value in nested array

Array recursion is a bit of a bear to tackle for any programmer.

While working on an HL7 parser,  I needed to be able to determine where in the HL7 message a certain string was located.   As I parsed the HL7 message into an array,  I needed to do a recursive search.

There are many solutions out there,  but when I first tried to tackle this,  the ones that I found that worked,  would either only tell me if a value existed in a nested array, but not what the index was,  or would only give me the root index.

After much trial and error,  I finally came up with a solution that is elegant and will return the location index, regardless if its associative or numeric.

The key to recursion is writing a function that can call itself.

The logic I use is to iterate through an array using foreach,   check  if the current value is an array,   if so,  call the recursion function and concatenate the value returned (if any).

This gives me a bar delimited string,  showing me exactly where in the nested array my search string exists.

Here is my function:


<?php

function recurse($input,$string) {

if (!is_array($input)) {

return 'Input parameter must be an array!';

}

$out = ''; //As I'm returning a delimited string, I need to declare the output string

foreach($input as $key=>$val) {

if (is_array($val)) {

$r = recurse($val,$string);

if (strlen($r) > 0) { //checking the length prevents you from getting a return for every index

$out .= $key.'|'.$r; //I chose bar delimited, you can change this to whatever, or even use an array

}

} else {

if ($val == $string) {

$out .= $key;

}
}

}

return $out;
}

?>

While I wrote this for HL7 parsing, I’ve created a script with some generic arrays to demonstrate


$sarr = array(

 'BILLY' => 'BLASTOFF',
 'RUBBER' => 'DUCKY'

);

$narr = array(

 'FIVE' => 5,
 'SIX' => 6,
 'SEVEN' => 7,
 'TOYS' => $sarr

);

$test = array (

 'ONE' => 1,
 'TWO' => 2,
 'THREE' => 3,
 'FOUR' => $narr,

);

echo '<pre>';
print_r(recurse($test,2));
echo '<br>';
print_r(recurse($test,7));
echo '<br>';
print_r(recurse($test,'DUCKY'));

and here’s the output!

 

TWO
FOUR|SEVEN
FOUR|TOYS|RUBBER