【问题标题】:How to use a string as an array index path to retrieve a value?如何使用字符串作为数组索引路径来检索值?
【发布时间】:2010-12-13 05:20:13
【问题描述】:

假设我有一个类似的数组:

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
}

【问题讨论】:

    标签: php arrays


    【解决方案1】:

    稍后,但是...希望对某人有所帮助:

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

    现在 itens 是你想要的数组的一部分。

    []的

    实验室

    【讨论】:

      【解决方案2】:

      您可以使用数组作为路径(从左到右),然后使用递归函数:

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

      【讨论】:

      • 不错。复制粘贴注意事项:对“getValue”的递归调用与函数名“get_value”不完全匹配。它们应该匹配才能正常工作。
      【解决方案3】:

      这是一个老问题,但由于此问题经常出现,因此已被引用。

      有递归函数,但我使用引用:

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

      【讨论】:

        【解决方案4】:

        尝试以下方法,其中 $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。

        【讨论】:

          【解决方案5】:
          function($indexPath, $arrayToAccess)
          {
              eval('$return=$arrayToAccess'.$indexPath.';');
              return $return;
          }
          

          【讨论】:

            【解决方案6】:

            你必须解析 indexPath 字符串。选择一些分隔符(例如“.”),阅读文本直到“。”那将是第一个键,然后阅读 rest 直到下一个,这将是下一个键。这样做直到没有更多的点。

            您可以将密钥存储在数组中。在这个数组上执行 foreach 循环以获取寻找的元素。

            【讨论】:

              【解决方案7】:

              如果字符串解析是您想要的方式,这是完成工作的一种方法。

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

              【讨论】:

                【解决方案8】:

                preg_match_all,循环浏览匹配的结果会让你接近你想要的结果。您需要小心此处列出的所有丢失信息的策略。例如,您必须设计一些方法来确保 55 保持为 int 类型并且不被解析为类型 string。

                【讨论】:

                  【解决方案9】:

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

                  【讨论】:

                    【解决方案10】:

                    如果您已经知道要提取的确切数组元素,为什么还要编写一个函数来执行此操作?只是有什么问题

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

                    【讨论】:

                    • 我也面临同样的问题。我有一个复杂的数组。我需要找到某个键​​,获取它的地址,然后获取其他数据,然后插入该键。所以我基本上需要存储一个 inxes 的地址,他们通过它来处理一个项目。
                    猜你喜欢
                    • 2020-12-08
                    • 1970-01-01
                    • 1970-01-01
                    • 2011-04-10
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多