2009-11-04 93 views
8

讓說我有一個數組,如:如何使用字符串作爲數組索引路徑來檢索值?

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

     ) 

) 

我希望能夠建立我可以通過一個字符串函數將作爲數組的索引路徑和不使用eval()返回相應的數組值。那可能嗎?

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 
} 

回答

9

你可以用一個數組作爲路徑(從左至右),然後遞歸函數:

$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

不錯。注意複製和粘貼:遞歸調用'getValue'並不完全匹配函數名'get_value'。他們應該匹配才能正常工作。 – grossvogel 2010-06-01 17:07:29

+0

這是現在修復的 – Ash 2012-10-30 11:12:29

+0

這是一個很好的例子!謝謝@manji! – Michael 2014-10-25 16:47:20

0

您必須解析indexPath字符串。選擇一些分隔符(例如「。」),直到閱讀文本「。」。那將是第一把鑰匙,然後再讀下去,直到下一把鑰匙。那樣做,直到沒有更多的點。

你肯存儲密鑰在數組中。對這個數組執行foreach循環以獲取搜索元素。

-1

如果你已經知道你正在提取的確切的數組元素,爲什麼寫一個函數來做呢?出了什麼問題只是

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

我面臨着同樣的問題。我有一個複雜的數組。我需要找到一個特定的密鑰,得到它的地址,然後獲得額外的數據,然後插入該密鑰。所以我基本上需要存儲一個inxes的地址,並且他們通過它來處理一個項目。 – 2013-11-15 15:17:02

0

這裏是爲了完成工作的一種方式,如果字符串解析是你想要去的方式。

$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

一個preg_match_all,通過匹配的結果循環會給你接近你想要的結果。您需要小心使用此處列出的所有策略以查找丟失的信息。例如,你必須設計一些方法來確保55保持爲int類型並且不被解析爲類型字符串。

16

晚了一點,但是......希望可以幫助別人:

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

現在itens是你想要的陣列的一部分。

的[]

實驗室

+1

真是太棒了!謝啦 :) – CoR 2014-06-17 14:33:11

2

這是一個老問題,但這個問題出現頻繁它已被引用。

有遞歸函數,但我使用的引用:

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

嘗試使用以下其中$ indexPath被格式化等的文件路徑即

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

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

例如使用問題中的數據,$ indexPath ='1/Data/name/first'將返回$ value = Jane。

0

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

可能使用

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

$status=[]; 

    $status['updated']=true; 

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

       //do something... 

     } 

資源

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

1
function($indexPath, $arrayToAccess) 
{ 
    eval('$return=$arrayToAccess'.$indexPath.';'); 
    return $return; 
} 
相關問題