atyagi
atyagi

Reputation: 300

Search value in multidimension array and keep keys association

I have this array converted from xml of webservice. I have 500 items in this array. I want to search any value and return all found array items with key association ( similar to database select query ). So if I search 'dummy' then it should return first item of this array.

Array
(
    [12.12.2014] => Array
        (
            [7] => Array
                (
                    [id] => 1672
                    [date] => 12.12.2014
                    [description] => rummy dummy data
                    [room] => delux
                    [Type] => garden
                    [from] => 17:00
                    [to] => 17:45
                    [assets] => Array
                        (
                            
                [asset] => Array
                                (
                                    [0] => Array
                                        (
                                            [number] => 5275
                                            [detail] => primary one
                                        )

                    [1] => Array
                                        (
                                            [number] => 19
                                            [detail] => secondary one
                                        )

                                )

                        )

                    [references] => Array
                        (
                            [reference] => Array
                                (
                                    [personnumber] => 479470
                                    [type] => worker
                                    [name] => David
                                    [department] => Sales
                                    [cv] => Array
                                        (
                    [pdetails] => follow later  
                                        )

                                    [profile] => True
                                )

                        )

                )

        )
    
       [13.12.2014] => Array
        (
            [17] => Array
                (
                    [id] => 1672
                    [date] => 13.12.2014
                    [description] => brown fox jump
                    [room] => star
                    [Type] => city
                    [from] => 17:00
                    [to] => 17:45
                    [assets] => Array
                        (
                            [asset] => Array
                                (
                                   [number] => 5275
                                   [detail] => prime two
                                )

                        )

                    [references] => Array
                        (
                            [reference] => Array
                                (
                                    [personnumber] => 479470
                                    [type] => manager
                                    [name] => Albert
                                    [department] => Purchase
                                    [cv] => Array
                                        (
                    [pdetails] => follow later  
                                        )

                                    [profile] => True
                                )

                        )

                )

        )

)

I tried stripos to search string in array value and in_array based functions but either it gives incorrect result or key association is not maintained.

I am unable to find a way to maintain key->value.

function search($array, $key, $value) 
{ 
    $results = array(); 

    if (is_array($array)) 
    { 
        if (isset($array[$key]) && $array[$key] == $value) 
            $results[] = $array; 

        foreach ($array as $subarray) 
            $results = array_merge($results, search($subarray, $key, $value)); 
    } 

    return $results; 
} 

This may be worst function you have ever seen but this do the job. If some one can make it recursive ( array may be further deeper ).

function search_in_multi_array($srchvalue, $array)
    {
        $foundkey = '';
        if (is_array($array) && count($array) > 0)
            {
            foreach($array as $pkey => $pvalue)
                {
                foreach($pvalue as $ckey => $cvalue)
                    {
                    if (is_array($cvalue) && count($cvalue) > 0)
                        {
                        if(in_array($srchvalue,$cvalue))
                            {
                            $foundkey[$pkey][$ckey] = $cvalue;
                            }
                            foreach($cvalue as $dkey => $dvalue)
                                {
                                if(!is_array($dvalue))
                                    {
                                    $pos = stripos($dvalue, $srchvalue);
                                    if ($pos !== false)
                                        {
                                        $foundkey[$pkey][$ckey] = $cvalue; 
                                    }
                                }
                            }  
                        }
                    }
                }
            }
        return $foundkey;
    }

Function call - $needle = 'fox'; search_in_multi_array($needle, $my_array); This is the output

Array
(
    [13.12.2014] => Array
        (
            [17] => Array
                (
                    [id] => 1672
                    [date] => 13.12.2014
                    [description] => brown fox jump
                    [room] => star
                    [Type1] => city
                    [from] => 17:00
                    [to] => 17:45
                    [assets] => Array
                        (
                            [asset] => Array
                                (
                                    [number] => 5275
                                    [detail] => prime two
                                )

                        )

                    [references] => Array
                        (
                            [reference] => Array
                                (
                                    [personnumber] => 479470
                                    [Type1] => manager
                                    [name] => Albert
                                    [department] => Purchase
                                    [cv] => Array
                                        (
                                            [pdetails] => follow later
                                        )

                                    [profile] => 1
                                )

                        )

                )

        )

)

Upvotes: 0

Views: 260

Answers (3)

JimmyB
JimmyB

Reputation: 12610

You may want to have a look at XPath to run queries against the "raw" XML, see DOMXPath for example.

Something like /myRootTag/someDayTag[.//text()[contains(.,'MY_SEARCH_VALUE')]] should do the trick, selecting and returning all the someDayTag XML elements below the myRootTag which have the text MY_SEARCH_VALUE in any child node.

Upvotes: 0

KIKO Software
KIKO Software

Reputation: 16688

I've made a simple routine that will extract the values in the array you're looking for:

function search_keys($needle,$haystack)
{
  foreach($haystack as $key => $value)
  {
    if (is_array($value)) $output[$key] = search_keys($needle,$value);
    else if (strpos($value,$needle) !== FALSE) $output[$key] = $value;
  }
  return isset($output) ? $output : NULL; // prevent warning
}

echo '<pre>';
print_r(search_keys('garden',$data));
echo '</pre>';

This will return 'garden' as:

Array
(
    [12.12.2014] => Array
        (
            [7] => Array
                (
                    [Type] => garden
                )

        )

)

You can further process the output of this function, or change the function, as needed.

Upvotes: 0

nileshsani
nileshsani

Reputation: 38

You can use array_search() function to look through the array values. But array_search only looks in single-dimensional array.

Since you have a multi-dimensional array, you can write custom recursive function to search recursively in the array

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 please note, using array_search() is a easier approach but not a optimised function. Which means if you're more concerned about your memory utilisation then I would also addtionally suggest.

  • Create a new array say 'dictionary' and store them like $dictonary[<key-searched>] = array('12.12.2014', '13.12.2014')
  • So you process them once, and cache them
  • So next time when you want search again for the same key, you can first check if the key exists in dictionary. If exists return from there, else use array_search and cache the results in dictionary

Its always easier to search by key-value than to search in a multi-dimensional array.

Upvotes: 0

Related Questions