3

I have an array in PHP which is multidimensional. It can have any number of levels as it is generated dynamically. None of the arrays contained in the array are empty and all have keys set.

I am looking for a way to get all array keys into a new array. I know how to do it on a single layered array but I am stuck as I don't know how many levels deep the array will go, it could be a single layered array itself or a 20 level multi dimensional array?

Thanks...

hadley
  • 621
  • 3
  • 7
  • 12

4 Answers4

7

For this particular application, I would use a class instead of arrays. The reason I say that is that it will be much easier to handle multiple levels, since you can have recursive functions in the class to access it. Here's a general example of what I'm talking about:

class Node {
    public $children = array();
    public $key;

    public function get_element_by_key($search_key){
        if($this->key == $search_key) return $this;
        foreach ($this->children as &$child) {
            if($child->get_element_by_key($search_key) != NULL){
                return $child;
            }
            else return NULL;
        }
    }
}

You could also add functions to add elements, a constructor to create an element and add to a parent and so on. Then you'd use the function get_element_by_key() (or similar) to access the elements. By the way, I haven't tried this code, I just wrote it to make a point. I bet you could get it to work though!

3
$ritit = new RecursiveIteratorIterator(new RecursiveArrayIterator($myArray), RecursiveIteratorIterator::SELF_FIRST);
$keys = array();
foreach ($ritit as $leafValue) {
    foreach (range(0, $ritit->getDepth()) as $depth) {
        $keys[] = $ritit->getSubIterator($depth)->key();
    }
}
print_r(array_unique($keys));

i added the RecursiveIteratorIterator::SELF_FIRST flag for good measure, although its not required in this case(the case that all sub arrays have at least one element). In fact, for this case, it would be more efficient without the flag.

goat
  • 31,486
  • 7
  • 73
  • 96
1

I'm not sure I understand you question entirely. If you want to store multi-dimensional keys in a single dimensional array you'll need some way to encode them. Then you can walk the entire "deep" structure and for each leaf node add the encoded key to a list.

If you just want to duplicate the array, the same basically applies. You'll need to traverse the array, building the copy as you go, or use a deep copy function such as discussed at Deep copy of PHP array of references

The piece you may be missing is that a multi-dimensional array is just an array of arrays. Good stuff in oreilly's php book

Community
  • 1
  • 1
easel
  • 3,982
  • 26
  • 28
1

If you want to gather all the keys as the values of a new array, the following should work for you.

// Function to recursively gather keys
function getKeys(&$keyArray, $parentArray) {
    if (!is_array($parentArray) || count($parrentArray) === 0) {
        return;
    }
    foreach ($parentArray as $key => $element) {
        $keyArray[] = $key;
        if (is_array($element)) {
            getKeys($keyArray, $element);
        }
    }
}

// Usage
$arrayToBeChecked = array(array(array(...
$arrayToHoldKeys;
getKeys($arrayToHoldKeys, $arrayToBeChecked);
Litty
  • 1,856
  • 1
  • 16
  • 35
  • Yes this is what I was looking for. I new I could do it with a class or whatever but it is better passing by reference in my eyes thanks :) – hadley Jun 03 '12 at 03:00
  • Glad to hear. But be sure to keep the classes in mind, people _do_ use them for a reason. Also, if this is your "answer," I'd appreciate you marking it as such! – Litty Jun 03 '12 at 03:08