2009-11-04 4 views
8

Lassen Sie sagen, ich habe ein Array wie:Wie verwende ich eine Zeichenfolge als Array-Indexpfad, um einen Wert abzurufen?

Array 
(
    [0] => Array 
     (
      [Data] => Array 
       (
        [id] => 1 
        [title] => Manager 
        [name] => John Smith 
       ) 
     ) 
    [1] => Array 
     (
      [Data] => Array 
       (
        [id] => 1 
        [title] => Clerk 
        [name] => 
         (
          [first] => Jane 
          [last] => Smith 
         ) 
       ) 

     ) 

) 

Ich mag eine Funktion bauen können, dass ich eine Zeichenfolge an, dass passieren kann, wird als Array-Index Pfad handeln und den entsprechenden Array-Wert zurück, ohne eval() mit . Ist das möglich?

function($indexPath, $arrayToAccess) 
{ 
    // $indexPath would be something like [0]['Data']['name'] which would return 
    // "Manager" or it could be [1]['Data']['name']['first'] which would return 
    // "Jane" but the amount of array indexes that will be in the index path can 
    // change, so there might be 3 like the first example, or 4 like the second. 

    return $arrayToAccess[$indexPath] // <- obviously won't work 
} 

Antwort

9

falsch könnten Sie ein Array als Pfad verwenden (von links nach rechts), dann eine rekursive Funktion:

$indexes = {0, 'Data', 'name'}; 

function get_value($indexes, $arrayToAccess) 
{ 
    if(count($indexes) > 1) 
    return get_value(array_slice($indexes, 1), $arrayToAccess[$indexes[0]]); 
    else 
    return $arrayToAccess[$indexes[0]]; 
} 
+0

Schön. Hinweis zu copy-and-pasters: Der rekursive Aufruf von 'getValue' stimmt nicht mit dem Funktionsnamen 'get_value' überein. Sie sollten übereinstimmen, um richtig zu funktionieren. – grossvogel

+0

Dies ist jetzt behoben – Ash

+0

Dies ist ein großartiges Beispiel! Danke @manji! – Michael

0

Sie müssen indexPath string analysieren. Wählen Sie ein Trennzeichen (zum Beispiel "."), Lesen Sie den Text bis "." das wäre der erste Schlüssel, dann lies Ruhe bis zum nächsten, das wäre der nächste Schlüssel. Mach das bis keine Punkte mehr sind.

Sie speichern Schlüssel in Array. Wiederholen Sie die Schleife in diesem Array, um das gesuchte Element zu erhalten.

-1

Wenn Sie bereits das genaue Array-Element kennen, das Sie herausziehen, warum schreiben Sie eine Funktion, um es zu tun? Was mit nur

$array[0]['data']['title'] 
+0

ich das gleiche Problem konfrontiert bin. Ich habe ein komplexes Array. Ich muss einen bestimmten Schlüssel finden, seine Adresse bekommen, dann zusätzliche Daten bekommen und in diesen Schlüssel einfügen. Also muss ich im Grunde eine Adresse von Inxes speichern und sie adressieren ein Element damit. –

0

Hier ist ein Weg, den Job zu erledigen, wenn der String-Parsing zu erhalten ist die Art, wie du gehen willst.

$data[0]["Data"]["stuff"] = "cake"; 

$path = "[0][\"Data\"]['stuff']"; 

function indexPath($path,$array){ 
    preg_match_all("/\[['\"]*([a-z0-9_-]+)['\"]*\]/i",$path,$matches); 

    if(count($matches[1]) > 0) { 
     foreach ($matches[1] as $key) { 
       if (isset($array[$key])) { 
         $array = $array[$key]; 
       } else { 
         return false; 
       } 
     } 
    } else { 
     return false; 
    } 

return $array; 
} 

print_r(indexPath($path,$data)); 
0

A preg_match_all, würde durch die angepassten Ergebnisse Radsport geben Sie das Ergebnis SCHLIEßEN Sie wollten. Sie müssen mit allen hier aufgeführten Strategien vorsichtig sein, um Informationen zu verlieren. Zum Beispiel müssen Sie einen Weg finden, um sicherzustellen, dass 55 als Typ int bleibt und nicht als Typ String geparst wird.

16

etwas später, aber ... Hoffnung hilft jemand:

// $pathStr = "an:string:with:many:keys:as:path"; 
$paths = explode(":", $pathStr); 
$itens = $myArray; 
foreach($paths as $ndx){ 
    $itens = $itens[$ndx]; 
} 

Jetzt itens ist der Teil des Arrays man wollte.

[] 's

Labs

+1

Wirklich brilliant! Danke, Mann :) – CoR

2

Dies ist eine alte Frage, aber es wird referenziert, da diese Frage häufig aufkommt.

Es gibt rekursiven Funktionen aber ich benutze eine Referenz:

function array_nested_value($array, $path) { 
    $temp = &$array; 

    foreach($path as $key) { 
     $temp =& $temp[$key]; 
    } 
    return $temp; 
} 

$path = array(0, 'Data', 'Name'); 
$value = array_nested_value($array, $path); 
2

Versuchen Sie, die folgenden, wo $ indexPath wie ein Dateipfad formatiert das heißt

'<array_key1>/<array_key2>/<array_key3>/...'. 

function($indexPath, $arrayToAccess) 
{ 
    $explodedPath = explode('/', $indexPath); 
    $value =& $arrayToAccess; 
    foreach ($explodedPath as $key) { 
     $value =& $value[$key]; 
    } 
    return $value; 
} 

z.B. Mit den Daten aus der Frage würde $ indexPath = '1/Data/name/first' $ value = Jane zurückgeben.

0

Neben abracadaver:

function array_nested_value($array, $path) { 

    foreach($path as $key) { 

     $array = $array[$key]; 
    } 

    return $array; 
} 

$path = array(0, 'Data', 'Name'); 
$value = array_nested_value($array, $path); 

Mögliche Verwendung

function get_array_value($array=array(), $path=array()){ 

    foreach($path as $key) { 

     if(isset($array[$key])){ 

      $array=$array[$key]; 
     } 
     else{ 

      $array=NULL; 
      break; 
     } 
    } 

    return $array; 
} 

function custom_isset($array=array(), $path=array()){ 

    $isset=true; 

    if(is_array($array)&&is_null(get_array_value($array, $path))){ 

     $isset=false; 
    } 

    return $isset; 
} 

function is($array=array(), $path=array()){ 

    $is=false; 

    if(is_array($array)){ 

     $array_value=get_array_value($array, $path); 

     if(is_bool($array_value)){ 

      $is=$array_value; 
     } 
    } 

    return $is; 
} 

Beispiel

$status=[]; 

    $status['updated']=true; 

     if(is($status,array('updated'))){ 

       //do something... 

     } 

Ressourcen

https://gist.github.com/rafasashi/0d3ebadf08b8c2976a9d

1
function($indexPath, $arrayToAccess) 
{ 
    eval('$return=$arrayToAccess'.$indexPath.';'); 
    return $return; 
} 
Verwandte Themen