2012-06-06 3 views
1

Все,Динамически Populating Многомерные массивы

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

Поставляемая функция отлично работает, но использует eval, мне было трудно найти подходящую функцию, которая не допускала ошибок без нее.

Начнем с массива:

$array = array(
      array(‘name’ => ‘Person1’, ‘username’ => ‘username1’, ‘join_date’ => 12233445566, ‘state’ => ‘NJ’), 
      array(‘name’ => ‘Person2’, ‘username’ => ‘username2’, ‘join_date’ => 12233445566, ‘state’ => ‘NJ’), 
      array(‘name’ => ‘Person3’, ‘username’ => ‘username3’, ‘join_date’ => 12233445996, ‘state’ => ‘NY’), 
      array(‘name’ => ‘Person4’, ‘username’ => ‘username4’, ‘join_date’ => 12233445996, ‘state’ => ‘NJ’), 
      array(‘name’ => ‘Person5’, ‘username’ => ‘username5’, ‘join_date’ => 12233445566, ‘state’ => ‘NJ’), 
      array(‘name’ => ‘Person6’, ‘username’ => ‘username6’, ‘join_date’ => 12233445566, ‘state’ => ‘NY’), 
      array(‘name’ => ‘Person7’, ‘username’ => ‘username7’, ‘join_date’ => 12233445776, ‘state’ => ‘NY’), 
      array(‘name’ => ‘Person8’, ‘username’ => ‘username8’, ‘join_date’ => 12233445566, ‘state’ => ‘NY’), 
      array(‘name’ => ‘Person9’, ‘username’ => ‘username9’, ‘join_date’ => 12233445996, ‘state’ => ‘NJ’), 
); 

Вот пример функции:

function createIndex($array, $index){ 
    $index_array = array(); 

    foreach($array as $result){ 

      if(is_array($index)){ 
       $key = '$index_array'; 
       for($i=0;$i<=sizeof($index)-1;$i++){ 
         $key .= "['{$result[$index[$i]]}']"; 
       } 
       $key .= "[]"; 
       eval("$key = \$result;"); 
      } 
      else{ 
       $index_array[$result[$index]] = $result; 
      } 
    } 

    return $index_array; 
} 

Призвание функция:

print_r(create_index($array, array(‘state’, ‘join_date’))); 

Нужный выход:

Array 
(
[NJ] => Array 
    (
     [12233445566] => Array 
      (
       [0] => Array 
        (
         [name] => Person1 
         [username] => username1 
         [join_date] => 12233445566 
         [state] => NJ 
        ) 

       [1] => Array 
        (
         [name] => Person2 
         [username] => username2 
         [join_date] => 12233445566 
         [state] => NJ 
        ) 

       [2] => Array 
        (
         [name] => Person5 
         [username] => username5 
         [join_date] => 12233445566 
         [state] => NJ 
        ) 

      ) 

     [12233445996] => Array 
      (
       [0] => Array 
        (
         [name] => Person4 
         [username] => username4 
         [join_date] => 12233445996 
         [state] => NJ 
        ) 

       [1] => Array 
        (
         [name] => Person9 
         [username] => username9 
         [join_date] => 12233445996 
         [state] => NJ 
        ) 

      ) 

    ) 

[NY] => Array 
    (
     [12233445996] => Array 
      (
       [0] => Array 
        (
         [name] => Person3 
         [username] => username3 
         [join_date] => 12233445996 
         [state] => NY 
        ) 

      ) 

     [12233445566] => Array 
      (
       [0] => Array 
        (
         [name] => Person6 
         [username] => username6 
         [join_date] => 12233445566 
         [state] => NY 
        ) 

       [1] => Array 
        (
         [name] => Person8 
         [username] => username8 
         [join_date] => 12233445566 
         [state] => NY 
        ) 

      ) 

     [12233445776] => Array 
      (
       [0] => Array 
        (
         [name] => Person7 
         [username] => username7 
         [join_date] => 12233445776 
         [state] => NY 
        ) 

      ) 

    ) 

) 

Вопрос: Какими способами вы побеждаете выше, чтобы получить одинаковые результаты из одного массива? Мне любопытно посмотреть, как это сделают другие.

Thanks

+0

Возможно, вы захотите использовать более богатую структуру данных. Основная проблема заключается в том, что у вас нет надежного способа провести различие между списком (числовыми, последовательными индексами, начинающимися с 0), и ключами, которые представляют собой столбец, с которым вы сформировали группы. Вы могли бы понять это, глядя на глубину ... но я думаю, что это становится уродливым. Я предполагаю, что простым решением было бы префикс всех ключей с строкой, кроме истинных числовых. – goat

ответ

0

Используя ссылки, я смог придумать функцию ниже. Он отлично работает!

Он автоматически определит, существует ли несколько листьев в конце дерева, и если да, то ветвь или лист. Кроме того, вы можете объединить, используя аргумент $merge_classifier. Это позволит вам объединить столбцы, например, count, что добавит значения вместе.

function createIndex($keys, Array $array, $merge_classifier = NULL, $return_array = array()) 
{    

    if(is_string($keys)){ 
     $tmp = $keys; 
     $keys = array(); 
     $keys[] = $tmp; 
    } 

    foreach($array as $result) { 
     $object = &$return_array; 

     foreach($keys as $index){ 
      if(!array_key_exists($result[$index], $object)) { 
       $object[$result[$index]] = array(); 
      } 
      $object = &$object[$result[$index]]; 
     } 

     if(!is_null($merge_classifier)){ 
      $object = array_merge($result, array($merge_classifier => ($result[$merge_classifier] + $object[$merge_classifier]))); 
     } 
     else{ 
      if(sizeof($object) > 0){ 
       $object[] = $result;  
      }else{ 
       $object = $result; 
      } 
     } 
    } 

    return $return_array; 
} 
1

Вот что я буду делать. Также обратите внимание, как вы можете перейти в $ index_array по ссылке. Я лично использую это в своем коде, поэтому я могу обрабатывать большие объемы данных в партиях и иногда удалять данные.

Это все о хранении переменных по ссылке:

function create_index($array, $indexes, &$index_array = array()) { 
    if(!is_array($indexes)) $indexes = array($indexes); 

    foreach($array as $result) { 
     $object = &$index_array; 

     foreach($indexes as $index){ 
      if(!array_key_exists((string)$result[$index], $object)) { 
       $object[(string)$result[$index]] = array(); 
      } 
      $object = &$object[(string)$result[$index]]; 
     } 
     $object[] = $result; 
    } 

    return $index_array; 
} 

Затем, чтобы использовать его:

// You can use it like you did in your question: 
print_r(create_index($array, array('state', 'join_date'))); 

// Or you can process in chunks: 

$results = array(); 

while(/* store data from database in $array */) { 
    create_index($array, array('state', 'join_date'), &$results); 
} 
1

я придумал в основном то же решение, как писал Райан, но я столкнулся с проблемами, когда ключ был int ... поэтому типажей к string для ключа массива ...

function createIndex($set, $indexes) 
{ 
    $return = array(); 

    if(!is_array($indexes)){ 
     $indexes = array($indexes); 
    } 

    foreach($set as $data){ 
     $curr =& $return; 
     foreach($indexes as $index){ 
      $key = (string)$data[$index]; 
      if(!is_array($curr[$key])){ 
       $curr[$key] = array(); 
      } 
      $curr =& $curr[$key]; 
     } 
     $curr[] = $data; 
    } 

    return $return; 
} 
Смежные вопросы