【问题标题】:php searching in multidimensional array of unknown depthphp在未知深度的多维数组中搜索
【发布时间】:2015-06-30 23:14:42
【问题描述】:

我尝试选择由json_decode() 构造的数组的数据。 原则上它是一个未知维度的多数组。

首先,我想在这个数组中递归搜索一个值。作为下一步,我想获得一些其他上维度的值。所以这里是一个例子:

我搜索:"2345"

....
$json[3][6]['journal']['headline']="news"
$json[3][6]['journal']['article']=2345
....
$json[8]['journal']['headline']="weather"
$json[8]['journal']['article']=2345
....

之后我想获取元素headline的值(返回“新闻”和“天气”)

可能是元素2345可以在不同维度找到!!!

【问题讨论】:

    标签: php arrays json search recursion


    【解决方案1】:

    只需创建一个用于编译未知数组的函数。试试这个

    $json[1][6]['journal']['headline']="news";
    $json[1][6]['journal']['article']=2345;
    $json[3][6]['journal']['headline']="HOT";
    $json[3][6]['journal']['article']=2345;
    $json[8]['journal']['headline']="weather";
    $json[8]['journal']['article']=2345;
    $json[10]['journal']['headline']="weather";
    $json[10]['journal']['article']=2345;
    
    $GLOBALS['list_scan'] = array();
    $result = array();
    
    foreach ($json as $key => $value) 
    {
        if (is_array($value)) {
            _compile_scan($key, $value);
        }
    }
    
    echo "<pre>";
    print_r($GLOBALS['list_scan']);
    echo "</pre>";
    
    $search = "2345";
    $keyword = "article";
    $keyFinder = "headline";
    
    foreach ($GLOBALS['list_scan'] as $key => $value)
    {
        if ($value == $search)
        {
            $addr = substr($key, 0, -(strlen($keyword))).$keyFinder;
            if (!empty($GLOBALS['list_scan'][$addr]))
            {
                $result[] = $GLOBALS['list_scan'][$addr];
            }
        }
    }
    echo "<pre>";
    print_r($result);
    echo "</pre>";
    
    
    function _compile_scan($index, $value)
    {
        $pointer =& $GLOBALS['list_scan'];
    
        foreach ($value as $key => $val) 
        {
            $temp = '';
            $temp = $index.'|'.$key;
            if (is_array($val))
            {
                // $pointer[$temp] = $val;
                _compile_scan($temp, $val);
            }
            else $pointer[$temp] = $val;
        }
    }
    

    输出:

    Array
    (
        [1|6|journal|headline] => news
        [1|6|journal|article] => 2345
        [3|6|journal|headline] => HOT
        [3|6|journal|article] => 2345
        [8|journal|headline] => weather
        [8|journal|article] => 2345
        [9|journal|headline] => Others
        [9|journal|article] => 234521
    )
    Array
    (
        [0] => news
        [1] => HOT
        [2] => weather
    )
    

    【讨论】:

      【解决方案2】:

      可能有人可以使用RecursiveIteratorIterator 对象来做到这一点,但我个人很难使用迭代器对象,所以这里有一个相当健壮的系统:

      <?php
      // This will traverse an array and find the
      // value while storing the base key    
      class RecurseLocator
          {
              public  static  $saved = array();
              public  static  $find;
              public  static  $trigger;
              public  static  function Initialize($find = false)
                  {
                      self::$find =   $find;
                  }
      
              public  static  function Recursive(array $array)
                  {
                      foreach($array as $key => $value) {
      
                              if(!isset(self::$trigger) || (isset(self::$trigger) && empty(self::$trigger))) {
                                      if(is_numeric($key))
                                          self::$trigger  =   $key;
                                  }
      
                              if(!is_array($value)) {
                                      if($value == self::$find) {
                                              self::$saved[self::$trigger]    =   $value;
                                          }
                                  }
      
                              if(is_array($value)) {
      
                                      $value  =   self::Recursive($value);
                                      if(!is_numeric($key))
                                          self::$trigger  =   "";
                                  }
      
      
                              $return[$key]   =   $value;
                          }
      
                      return $return;
                  }
          }
      
      // This class will traverse an array searching
      // for a specific key or keys
      class   RecurseSearch
          {
              public  $data;
              public  $compare;
      
              public  function Find($array = '',$find,$recursive = true)
                  {
                      $find   =   (is_array($find))? implode("|",$find):$find;
                      if(is_array($array)) {
      
                              foreach($array as $key => $value) {
      
                              if(preg_match("/$find/",$key))
                                  $this->compare[$key]    =   $value;
      
                                      if($recursive == true) {
                                              if(!is_array($value)) {
                                                      if(preg_match("/$find/",$key)) {
                                                              $this->data[$key][] =   $value;
                                                          }
      
                                                      $array[$key]    =   $value;
                                                  }
                                              else {
                                                      if(preg_match("/$find/",$key))
                                                          $this->data[$key][] =   $this->Find($value,$find);
      
                                                      $array[$key]    =   $this->Find($value,$find);
                                                  }
                                          }
                                      else {
                                              if(preg_match("/$find/",$key))
                                                  $this->data[$key]   =   $value;
                                          }
                                  }
      
                              $this->data =   (isset($this->data))? $this->data:false;
      
                              return $this;
                          }
                  }
          }
      
      // This function just wraps the RecurseSearch class
      function get_key_value($array = array(), $find = array(),$recursive = true)
          {
              $finder =   new RecurseSearch();
              return $finder->Find($array,$find,$recursive);
          }
      

      用法:

          $json[3][6]['journal']['headline']  =   "news";
          $json[3][6]['journal']['article']   =   2345;
          $json[8]['journal']['headline']     =   "weather";
          $json[8]['journal']['article']      =   2345;
          $json[4][1]['journal']['headline']  =   "news";
          $json[4][1]['journal']['article']   =   22245;
          $json[5]['journal']['headline']     =   "weather";
          $json[5]['journal']['article']      =   233345;
      
          // Set the search criteria
          RecurseLocator::Initialize(2345);
          // Traverse the array looking for value
          $arr    =   RecurseLocator::Recursive($json);
          // If found, will be stored here
          $iso    =   RecurseLocator::$saved;
      
          /* $iso looks like:
          Array
          (
              [3] => 2345
              [8] => 2345
          )
          */
      
          // Loop through the $iso array
          foreach($iso as $key => $value) {
                  // Save to new array your search results
                  $new[]  =   get_key_value($json[$key],array("headline","article"),true);
              }
      
          /* $new looks like:
      Array
      (
          [0] => RecurseSearch Object
              (
                  [data] => Array
                      (
                          [headline] => Array
                              (
                                  [0] => news
                              )
      
                          [article] => Array
                              (
                                  [0] => 2345
                              )
                      )
      
                  [compare] => Array
                      (
                          [headline] => news
                          [article] => 2345
                      )
              )
      
          [1] => RecurseSearch Object
              (
                  [data] => Array
                      (
                          [headline] => Array
                              (
                                  [0] => weather
                              )
      
                          [article] => Array
                              (
                                  [0] => 2345
                              )
                      )
      
                  [compare] => Array
                      (
                          [headline] => weather
                          [article] => 2345
                      )
              )
      )
          */
      ?>
      

      顺便说一句,上面的类存储多个在[data]中找到的,然后将它们也存储在[compare]中,但是如果在一个数组中找到多个相同的键,[compare]将覆盖自己[data] 将继续添加值。

      【讨论】:

        猜你喜欢
        • 2017-07-03
        • 2017-05-09
        • 1970-01-01
        • 1970-01-01
        • 2019-05-10
        • 1970-01-01
        • 2020-03-24
        • 2021-01-13
        • 2023-03-25
        相关资源
        最近更新 更多