2012-06-03 6 views
2

У меня есть массив в PHP, который является многомерным. Он может иметь любое количество уровней, поскольку он генерируется динамически. Ни один из массивов, содержащихся в массиве, пуст, и все имеют ключи.PHP многомерный массив ключей в один массив?

Я ищу способ получить все ключи массива в новый массив. Я знаю, как это сделать на одном многоуровневом массиве, но я застрял, так как не знаю, сколько уровней будет в глубине массива, это может быть один многоуровневый массив или 20-уровневый многомерный массив?

Благодаря ...

+0

Что относительно ключей, которые относятся к массивам? Должны ли они быть включены в результирующий набор? – mjhennig

+2

В этом случае вы хотите использовать [рекурсия] (http://en.wikipedia.org/wiki/Recursion_%28computer_science%29). –

+0

вы хотите * просто * ключ? или ключ типа «id», то есть 'top_key' с дочерним' top_key-next_key' и т. д.? – Jon

ответ

1

Если вы хотите собрать все ключи в качестве значений нового массива, то для вас должно работать следующее.

// 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); 
+0

Да, это то, что я искал. Я новичок, я мог бы сделать это с классом или что-то еще, но лучше пропустить по ссылке в моих глазах спасибо :) – hadley

+0

Рад слышать. Но не забудьте держать классы в виду, люди используют их по какой-то причине. Кроме того, если это ваш «ответ», я был бы признателен, если вы отметите это как таковое! – Litty

+1

Без проблем приятель :) – hadley

1

Я не уверен, что понимаю вас вопрос полностью. Если вы хотите хранить многомерные ключи в одномерном массиве, вам понадобится какой-то способ их кодирования. Затем вы можете пройти всю «глубокую» структуру, и для каждого листового узла добавить кодированный ключ в список.

Если вы просто хотите дублировать массив, то это в основном применяется. Вам нужно будет пройти по массиву, построив копию по ходу дела или использовать функцию глубокой копии, например, обсуждаемую в Deep copy of PHP array of references.

Возможно, вам не хватает частичного массива, который представляет собой массив массивов , Хороший материал в oreilly's php book

7

Для этого конкретного приложения я бы использовал класс вместо массивов. Причина, по которой я говорю, заключается в том, что с несколькими уровнями будет намного проще обрабатывать, так как вы можете иметь рекурсивные функции в классе для доступа к нему. Вот общий пример того, что я говорю:

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; 
     } 
    } 
} 

Можно также добавить функции для добавления элементов, конструктор для создания элемента и добавить к родителю и так далее. Затем вы можете использовать функцию get_element_by_key() (или аналогичную) для доступа к элементам. Кстати, я не пробовал этот код, я просто написал его, чтобы сделать точку. Готов поспорить, вы можете заставить его работать!

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)); 

я добавил RecursiveIteratorIterator::SELF_FIRST флаг для хорошей мерой, хотя его не требуется в данном случае (случай, что все суб массивы имеют, по меньшей мере, один элемент). Фактически, для этого случая было бы более эффективно без флага.

Смежные вопросы