4

I have a deep and long array (matrix). I only know the product ID. How found way to product?

Sample an array of (but as I said, it can be very long and deep):

Array( [apple] => Array( [new] => Array( [0] => Array([id] => 1) [1] => Array([id] => 2)) [old] => Array( [0] => Array([id] => 3) [1] => Array([id] => 4)) ) ) 

I have id: 3, and i wish get this: apple, old, 0

Thanks

1
  • Um, do you mean an upheap kind of thing? Commented Jul 28, 2010 at 19:47

4 Answers 4

1

You can use this baby:

function getById($id,$array,&$keys){ foreach($array as $key => $value){ if(is_array( $value )){ $result = getById($id,$value,$keys); if($result == true){ $keys[] = $key; return true; } } else if($key == 'id' && $value == $id){ $keys[] = $key; // Optional, adds id to the result array return true; } } return false; } // USAGE: $result_array = array(); getById( 3, $products, $result_array); // RESULT (= $result_array) Array ( [0] => id [1] => 0 [2] => old [3] => apple ) 

The function itself will return true on success and false on error, the data you want to have will be stored in the 3rd parameter.

You can use array_reverse(), link, to reverse the order and array_pop(), link, to remove the last item ('id')

Sign up to request clarification or add additional context in comments.

Comments

1

Recursion is the answer for this type of problem. Though, if we can make certain assumptions about the structure of the array (i.e., 'id' always be a leaf node with no children) there's further optimizations possible:

<?php $a = array( 'apple'=> array( 'new'=> array(array('id' => 1), array('id' => 2), array('id' => 5)), 'old'=> array(array('id' => 3), array('id' => 4, 'keyname' => 'keyvalue')) ), ); // When true the complete path has been found. $complete = false; function get_path($a, $key, $value, &$path = null) { global $complete; // Initialize path array for first call if (is_null($path)) $path = array(); foreach ($a as $k => $v) { // Build current path being tested array_push($path, $k); // Check for key / value match if ($k == $key && $v == $value) { // Complete path found! $complete= true; // Remove last path array_pop($path); break; } else if (is_array($v)) { // **RECURSION** Step down into the next array get_path($v, $key, $value, $path); } // When the complete path is found no need to continue loop iteration if ($complete) break; // Teardown current test path array_pop($path); } return $path; } var_dump( get_path($a, 'id', 3) ); $complete = false; var_dump( get_path($a, 'id', 2) ); $complete = false; var_dump( get_path($a, 'id', 5) ); $complete = false; var_dump( get_path($a, 'keyname', 'keyvalue') ); 

2 Comments

you can do this without the global var and it'd be a much better example if you did.
@Mark: It's a simple example - and can be easily refactored to use static $complete variable declaration instead. Feel free to post your own solution!
0

I tried this for my programming exercise.

<?php $data = array( 'apple'=> array( 'new'=> array(array('id' => 1), array('id' => 2), array('id' => 5)), 'old'=> array(array('id' => 3), array('id' => 4)) ), ); ####print_r($data); function deepfind($data,$findfor,$depth = array() ){ foreach( $data as $key => $moredata ){ if( is_scalar($moredata) && $moredata == $findfor ){ return $depth; } elseif( is_array($moredata) ){ $moredepth = $depth; $moredepth[] = $key; $isok = deepfind( $moredata, $findfor, $moredepth ); if( $isok !== false ){ return $isok; } } } return false; } $aaa = deepfind($data,3); print_r($aaa); 

Comments

-1

If you create the array once and use it multiple times i would do it another way...


When building the initial array create another one

 $id_to_info=array(); $id_to_info[1]=&array['apple']['new'][0]; $id_to_info[2]=&array['apple']['new'][2]; 

1 Comment

Why did i get a -1 , i'm curious ?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.