2015-01-08 2 views
0

У нас есть массив со следующими значениями:Transform ассоциативный массив рекурсивный

$a = array("a", "a.b", "a.b.c", "X", "X.Y", "X.Y.Z"); 

И цель, чтобы изменить первый массив в следующем составе:

$a = array(
    "a" => array(
     "b" => array(
      "c" => array(), 
     ), 
    ), 
    "X" => array(
     "Y" => array(
      "Z" => array(), 
     ), 
    ), 
); 

Почему я спрашиваю? У моего клиента есть таблица для категорий магазинов. И эти категории находятся в одной колонке (упрощенной!):

+-----------------------+ 
|id |  name  | 
+---|-------------------+ 
| 4 | A     | 
| 5 | A.B    | 
| 6 | A.B.C    | 
| 7 | X     | 
| 8 | X.Y    | 
| 9 | X.Y.Z    | 
+-----------------------+ 

Как я могу это сделать с помощью PHP?

EDIT:

Мои текущие решения "/ Trys"

<?php 

$arr = array(
    "a", 
    "a.b", 
    "a.b.c", 
    "x", 
    "x.y", 
    "x.y.z", 
); 

$container = array(); 
$updateMe = array(); 

foreach($arr as $key => $value) { 
    $cleanName = explode(".", $value); 

    foreach($cleanName as $keyArray => $valueArray) { 
     for($c = 0;$c<$keyArray+1;$c++) { 
      $updateMe[$cleanName[$c]] = array(); 
     } 


    } 

    $container[$cleanName[0]] = $updateMe; 
    unset($updateMe); 
} 

echo "<pre>"; 
var_dump($container); 
echo "===\r\n"; 

Мой выход:

array(2) { 
    ["a"]=> 
    array(3) { 
    ["a"]=> 
    array(0) { 
    } 
    ["b"]=> 
    array(0) { 
    } 
    ["c"]=> 
    array(0) { 
    } 
    } 
    ["x"]=> 
    array(3) { 
    ["x"]=> 
    array(0) { 
    } 
    ["y"]=> 
    array(0) { 
    } 
    ["z"]=> 
    array(0) { 
    } 
    } 
} 
=== 

РЕШЕНИЕ

<?php 

$arr = array(
    "a", 
    "a.b", 
    "a.b.c", 
    "x", 
    "x.y", 
    "x.y.z", 
); 

$array = array(); 
$test = array(); 

foreach($arr as $key => $text) { 
    $array = array(); 
    foreach(array_reverse(explode('.', $text)) as $key) $array = array($key => $array); 

    $test[] = $array; 
} 

echo "<pre>"; 
var_dump($test); 
echo "===\r\n"; 
+0

И каков ваш вопрос? –

+0

Ваш прием не имеет смысла! – Rizier123

+0

Не ясно, почему вы исходный массив состоит из 6 элементов, но ваш результат массив имеет только 2. –

ответ

1

Вы можете использовать принятый ответ from this question или this answer from the same question, чтобы получить a good starting point (я воспользуюсь вторым ответом, потому что в этом примере он короче).

$out = array(); 
foreach ($a as $string) { 
    $array = array(); 
    foreach(array_reverse(explode('.', $string)) as $key) { 
     $array = array($key => $array); 
    } 
    $out[] = $array; 
} 

Это даст вам числовой массив, основанный ключ, так, то вы можете переложить на первый уровень массива с помощью an answer from this question:

$out = call_user_func_array('array_merge', $out); 

И ваш result:

Array 
(
    [a] => Array 
     (
      [b] => Array 
       (
        [c] => Array 
         (
         ) 

       ) 

     ) 

    [X] => Array 
     (
      [Y] => Array 
       (
        [Z] => Array 
         (
         ) 

       ) 

     ) 

) 
+0

Вот этот фрагмент, который я искал! Большое спасибо! – Tyralcori

2

Мне нравится использовать ссылки в PHP. Это может быть не лучшее решение, но, похоже, оно работает.

<?php 
$arr = array(
    "a", 
    "a.b", 
    "a.b.c", 
    "x", 
    "x.y", 
    "x.y.z", 
); 

$output = array(); 

foreach($arr as $path){ 
    // Create a reference to the array 
    // As we go deeper into the path we will move this reference down 
    $setArray =& $output; 

    foreach(explode('.', $path) as $key){ 
     // If this key does not exist, create it 
     if(!isset($setArray[$key])){ 
      $setArray[$key] = array(); 
     } 

     // Move the reference down one level, 
     // so that the next iteration will create 
     // the key at the right level 
     $setArray =& $setArray[$key]; 
    } 
} 

// Destroy the reference, so that we don't accidently write to it later 
unset($setArray); 

var_dump($output); 
+2

Еще один отличный ответ! Преимущество этого решения состоит в том, что в массиве нет дублированного содержимого/дублированных слоев/элементов! – Tyralcori

0

Это должно работать для вас:

<?php 

    $a = array("a", "a.b", "a.b.c", "1", "1.2", "1.2.3"); 
    $results = array(); 

    function stringToArray($path) { 

     $pos = strpos($path, "."); 

     if ($pos === false) 
      return array($path => ""); 

     $key = substr($path, 0, $pos); 
     $path = substr($path, $pos + 1); 

     return array(
      $key => stringToArray($path) 
     ); 

    } 

    foreach($a as $k => $v) { 
     if(substr_count(implode(", ", $a), $v) == 1) 
      $results[] = stringToArray($v); 
    } 

    $results = call_user_func_array('array_merge', $results); 
    print_R($results); 

?> 

Выход:

Array ([a] => Array ([b] => Array ([c] =>)) [0] => Array ([2] => Array ([3] =>))) 
0

просто хитрый

$a = array("a", "a.b", "a.b.c", "X", "X.Y", "X.Y.Z"); 

    $res = array(); 
    foreach ($a as $str) { 
     $str = str_replace('.','"]["',$str); 
     $tricky = '$res["'.$str.'"]'; 
     eval ($tricky.' = array();'); 
}; 
+0

Использование eval для этого - плохая новость. –

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