Dereleased's solution will be faster I guess (as it uses internal loops), mine can also deal with array values for object_id keys. Your tradeoff ;) function find_all($needle, array $haystack, array &$result = null) { // This is to initialize the result array and is only needed for // the first call of this function if(is_null($result)) { $result = array(); } foreach($haystack as $key => $value) { // Check whether the key is the value we are looking for. If the value // is not an array, add it to the result array.
If($key === $needle &&! Is_array($value)) { $result = $value; } if(is_array($value)) { // If the current value is an array, we perform the same // operation with this 'subarray'. Find_all($needle, $value, $result); } } // This is only needed in the first function call to retrieve the results return $result; } As you can see, the result array is given to every call of the function as reference (denoted by the & ).
This way, every recursive call of this function has access to the same array and can just add a find You can do: $values = find_all('object_id', $array) It gives me for your array: Array ( 0 => 12061 1 => 100012061 2 => 1000000000015 3 => 10001 4 => 12862 5 => 12876 6 => 1206102000 7 => 1206104000 8 => 1206101000 9 => 1206105000 10 => 1206106000 11 => 10017 12 => 100010017 13 => 300306 14 => 12894 15 => 12862 16 => 12876 17 => 1001701000 18 => 11990 19 => 100011990 20 => 12862 21 => 12876 22 => 10017 23 => 12894 ).
Dereleased's solution will be faster I guess (as it uses internal loops), mine can also deal with array values for object_id keys. Your tradeoff ;) function find_all($needle, array $haystack, array &$result = null) { // This is to initialize the result array and is only needed for // the first call of this function if(is_null($result)) { $result = array(); } foreach($haystack as $key => $value) { // Check whether the key is the value we are looking for. If the value // is not an array, add it to the result array.
If($key === $needle &&! Is_array($value)) { $result = $value; } if(is_array($value)) { // If the current value is an array, we perform the same // operation with this 'subarray'. Find_all($needle, $value, $result); } } // This is only needed in the first function call to retrieve the results return $result; } As you can see, the result array is given to every call of the function as reference (denoted by the &).
This way, every recursive call of this function has access to the same array and can just add a find. You can do: $values = find_all('object_id', $array); It gives me for your array: Array ( 0 => 12061 1 => 100012061 2 => 1000000000015 3 => 10001 4 => 12862 5 => 12876 6 => 1206102000 7 => 1206104000 8 => 1206101000 9 => 1206105000 10 => 1206106000 11 => 10017 12 => 100010017 13 => 300306 14 => 12894 15 => 12862 16 => 12876 17 => 1001701000 18 => 11990 19 => 100011990 20 => 12862 21 => 12876 22 => 10017 23 => 12894 ).
You can type-hint $result to array in the function declaration as well, as initializing it to null is not only valid but will handle cases where it doesn't exist in an acceptable way. Just sayin' =) – Dereleased Feb 2 '10 at 21:20 True, thank you. I guess I was just lazy ;) – Felix Kling Feb 2 '10 at 21:21 Can you explain working of this code, because I am not able to understand working on this code.
Would appreciate if you can share some insights on it – Rachel Feb 2 '10 at 21:31 @Rachel: I added some comments. – Felix Kling Feb 2 '10 at 21:38 @Felis: Thank you for the comments, is there any way we can get duplicate values too as right now duplicate values are being removed. – Rachel Feb 2 '10 at 21:48.
$res = array(); foreach (new RecursiveIteratorIterator(new RecursiveArrayIterator($arr)) as $k => $v) { if ($k === 'object_id') { $res = $v; } }.
1 for using Spl – Gordon Feb 2 '10 at 22:47.
My testing had to be simple because I am not going to take the time to translate whatever dump you have provided into a working array; if this doesn't work, please provide a var_export of the array for testing purposes. This, however, sounds like a job for array_walk_recursive(). $coll = array(); function array_get_keys($value, $key, $c) { if (strcasecmp($key,'object_id')==0) { array_push($c0,$value); } } array_walk_recursive($array, 'array_get_keys', array(&$coll)); The last parameter to array_walk_recursive is a reference in an array because, since call-time pass-by-reference has been deprecated, that is the only way (other than some convoluted object structure See Below) to pass a reference to the container to the handler function.
This code should populate $coll with all the values that have 'object_id' as their key. It will not work for cases where 'object_id' is an array, because this is known behavior of array_walk_recursive() (that is, the callback function is not initiated for elements which are themselves arrays). EDIT (for great justice): The object structure is not actually that convoluted, so if you wish to avoid extraneous array/reference constructs, here's how to do it: $coll = new ArrayObject; function array_get_keys($value, $key, $c) { if (strcasecmp($key,'object_id')==0) { $c = $value; } } array_walk_recursive($array, 'array_get_keys', $coll); How it works PHP's array_walk_recursive() function takes a given array for its first parameter and iterates over each key/value pair.
If the value is scalar, it passes the key/value combination to some user-defined callback function; however, if the value is an array, then array_walk_recursive() will recursively call itself, and continue to behave in the same manner. It will work in this way until it has looped through every element in the array. The second parameter is the callback function to use; in this case, I have written and declared a function (array_get_keys) and passed its name as a string in the second parameter.
Thus, the function is registered by array_walk_recursive() and is the function executed each time a key/value pair is processed. The third parameter in both examples is basically a piece of "extra" data we can pass to our callback function to alter its behavior -- in this case, it is an array (or in the second example, an ArrayObject container) which is (a) defined in the global scope and (b) used to store all the values for which $key == 'object_id' is true. In the first example, I use the syntax array(&$coll) to pass the collection variable, because that is the only way to pass a reference to the collection so that it can be modified in the global scope (otherwise, we have no way to retrieve the list).
In the second example, I declare $coll as an ArrayObject, which makes it implicitly passed by reference, so there is no need to contain it in an array to ensure it is modified in the global scope.
– Rachel Feb 2 '10 at 21:29 btw +1 because it is shorter than mine ;) (and probably (much?) faster)... – Felix Kling Feb 2 '10 at 21:41 Yes, it will give you all values for key == 'object_id', and insert them into an array, and I will add some more explanation. – Dereleased Feb 2 '10 at 22:02 Thank you Dereleased for the apt explanation. It really helped alot.
– Rachel Feb 2 '10 at 22:46.
Alternative to checking for object_id in foreach loop when using Spl Iterators: class KeyFilter extends FilterIterator { protected $acceptedKeys; // keys to return when iterating over the array public function __construct(array $keys, $iterator) { $this->acceptedKeys = $keys; parent::__construct($iterator); } public function accept() { // skip elements that return false when iterating return (in_array($this->key(), $this->acceptedKeys)); } } Subclasses extending FilterIterator must implement the accept() method. Internally, when iterating over your array with foreach, the filter iterator will call your accept method and skip any elements for which the test written in the method will return false. FilterIterators are stackable, so you can combine multiple FilterIterators to a Filter Chain, which makes this a very flexible approach.
You'd use it like this $yourArray = new KeyFilter(array('object_id' /* add more */), new RecursiveIteratorIterator( new RecursiveArrayIterator($yourArray))); foreach($yourArray as $key => $value) { // will only return elements with an object_id key echo $key, '--', $value, PHP_EOL; } More on SplIterators: http://www.phpro.org/tutorials/Introduction-to-SPL.html.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.