2016-08-08 44 views
0

Ich habe eine Liste von Strings, die jeweils Punkt notierte Werte enthalten. Ich möchte diese Liste in ein assoziatives Array mit jedem Segment der Punktnotation als Schlüssel in der entsprechenden Verschachtelungsebene konvertieren. Die tiefste Ebene der Verschachtelung sollte den Wert Boolean True haben. Es gibt keine Begrenzung für die Anzahl oder Punktsegmente, die eine Zeichenfolge enthalten kann, sodass der Code eine Rekursion ausführen muss, um das Ziel zu erreichen.Konvertieren Sie eine Liste mit Punkt notierten Strings in ein assoziatives Array (PHP)

Eingabebeispiel:

[ 
    'foo.bar', 
    'foo.bar.baz', 
    'foo.bar.qux', 
    'foo.qux', 
    'foo.quux', 
    'bar.baz', 
    'bar.qux', 
    'qux.quux', 
] 

Erforderliche Ausgabe:

[ 
    'foo' => [ 
     'bar' => [ 
      'baz' => true, 
      'qux' => true, 
     ], 
     'qux' => true, 
     'quux' => true, 
    ], 
    'bar' => [ 
     'baz' => true, 
     'qux' => true, 
    ], 
    'qux' => [ 
     'quux' => true 
    ] 
] 
+2

Also, was ist das Problem? Oder Sie brauchen uns nur, um den Code für Sie zu schreiben? – Sejanus

+0

Ich brauche ein wenig Hilfe mit der Logik –

+0

Bitte posten Sie Ihre Versuche, was Sie bisher versucht haben? –

Antwort

1

foreach einzige Lösung.

function convert(array $input) 
{ 
    $r = []; 
    foreach ($input as $dotted) { 
     $keys = explode('.', $dotted); 
     $c = &$r[array_shift($keys)]; 
     foreach ($keys as $key) { 
      if (isset($c[$key]) && $c[$key] === true) { 
       $c[$key] = []; 
      } 
      $c = &$c[$key]; 
     } 
     if ($c === null) { 
      $c = true; 
     } 
    } 
    return $r; 
} 
+0

Vorschlag: [Getting/Setting/Unsetting Array-Elemente mit dot-chained Notation] (http://qiita.com/mpyw/items/185c00306b7d7d6a06d0) – mpyw

+0

Danke für die prompte Antworten. Problem gelöst! –

0

Wenn Sie Ihr Start Array von Strings nennen $input, die $output Array in dem folgenden Code ist, was Sie wollen

$input=[...]; //original array 
$output=[]; //holds the results; 
foreach ($input as $line){ 
    $keys = explode('.',$line);//break each section into a key 
    $val = true;    //holds next value to add to array 
    $localArray = [];   //holds the array for this input line 
    for($i=count($keys)-1; $i>=0; $i--){ //go through input line in reverse order 
     $localArray = [$keys[$i]=>$val]; //store previous value in array 
     $val = $localArray;   //store the array we just built. it will be 
             //the value in the next loop 
    } 
    $output = array_merge_recursive($output,$localArray); 
} 

Live demo

+0

'$ output ['foo'] ['bar'] [0]' sollte nicht existieren ...? – mpyw

0
function convert($aa) { 
    $zz = []; 
    foreach($aa as $value) { 
    $bb = explode('.',$value); 
    $cc = count($bb); 
    for($ii = 0, $yy = &$zz; $ii < $cc ; $ii++) { 
     $key = $bb[$ii]; 
     if (array_key_exists($key,$yy) === false || is_array($yy[$key]) === false) { 
     $yy[$key] = []; 
     } 
     $yy = &$yy[$key]; 
    } 
    $key = $bb[$cc-1]; 
    if (array_key_exists($key,$yy) === false) { 
     $yy[$key] = true; 
    } 
    } 
    return $zz; 
} 
+1

Dieser Code wird ungültig, wenn 'foo.bar' nach' foo.bar.baz' erscheint. Sie sollten den Wert von $ yy [$ bb [$ cc-1]] überprüfen, bevor Sie true zuweisen. – mpyw

0

Sie können dies mit Zeiger und etwas Logik tun.

<?php 
$test = [ 
    'foo.bar', 
    'foo.bar.baz', 
    'foo.bar.qux', 
    'foo.qux', 
    'foo.quux', 
    'bar.baz', 
    'bar.qux', 
    'qux.quux', 
]; 

class Test 
{ 
    public $result = []; 

    public function check($array){ 
     foreach ($array as $value) { 
      $this->change($value); 
     } 
    } 

    public function change($string) 
    { 
     $explodedValues = explode('.',$string); 

     $pointerVariable = &$this->result; 

     foreach ($explodedValues as $explodedValue) { 

      if(!is_array($pointerVariable)){ 
       $pointerVariable = []; 
       $pointerVariable[$explodedValue] = true; 
       $pointerVariable = &$pointerVariable[$explodedValue]; 
      } else if(isset($pointerVariable[$explodedValue])){ 
       $pointerVariable = &$pointerVariable[$explodedValue]; 
      } else { 
       $pointerVariable[$explodedValue] = true; 
       $pointerVariable = &$pointerVariable[$explodedValue]; 
      } 

     } 
    } 
} 

$obj = new Test(); 
$obj->check($test); 

print_r($obj->result); 

Hope this

helfen