2009-11-04 64 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; 
} 
相关问题