简体   繁体   English

PHP在未知深度的多维数组中搜索

[英]php searching in multidimensional array of unknown depth

I try to select the data of an array that was constructed by json_decode() . 我尝试选择由json_decode()构造的数组的数据。 In principle it is an multiarray of unknown dimension. 原则上,它是一个未知维度的多数组。

First of all, I want to search recursively for a value in this array. 首先,我要递归搜索此数组中的值。 As a next step I want to get some other values of the upper dimension. 下一步,我想获取高维的其他一些值。 So here is an example: 所以这是一个例子:

I search for: "2345" 我搜索: "2345"

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

After that I want to get the value of the element headline (returning "news" and "weather") 之后,我想获取元素headline的值(返回“新闻”和“天气”)

It might be that the element 2345 can be found in different dimensions!!! 可能是元素2345尺寸不同!!!

Someone could probably do this with a RecursiveIteratorIterator object, but I personally have a hard time with iterator objects, so here is a fairly robust system: 有人可能可以使用RecursiveIteratorIterator对象来做到这一点,但是我个人很难使用Iterator对象,因此这是一个相当强大的系统:

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

USAGE: 用法:

    $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
                )
        )
)
    */
?>

Just as a side note, the above class stores multiple found in the [data] , and then stores them also in the [compare] , however the [compare] will overwrite itself if multiple same-keys are found in one array where as [data] will just keep adding values. 顺便提一句,上述类存储在[data]找到的多个,然后将它们也存储在[compare] ,但是,如果在一个数组中找到多个相同的键,则[compare]将覆盖自身,其中[data]只会继续增加价值。

just create a function for compile unknown array. 只需创建一个用于编译未知数组的函数即可。 try this 尝试这个

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

output: 输出:

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
)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM