如何在 PHP 中的多维数组中按键 =>值进行搜索

2022-08-30 06:40:14

有没有快速的方法可以获取在多维数组中找到键值对的所有子数组?我不能说数组有多深。

简单示例数组:

$arr = array(0 => array(id=>1,name=>"cat 1"),
             1 => array(id=>2,name=>"cat 2"),
             2 => array(id=>3,name=>"cat 1")
);

当我搜索key=name和value=“cat 1”时,函数应该返回:

array(0 => array(id=>1,name=>"cat 1"),
      1 => array(id=>3,name=>"cat 1")
);

我想这个函数必须是递归的,才能深入到最深的层次。


答案 1

法典:

function search($array, $key, $value)
{
    $results = array();

    if (is_array($array)) {
        if (isset($array[$key]) && $array[$key] == $value) {
            $results[] = $array;
        }

        foreach ($array as $subarray) {
            $results = array_merge($results, search($subarray, $key, $value));
        }
    }

    return $results;
}

$arr = array(0 => array(id=>1,name=>"cat 1"),
             1 => array(id=>2,name=>"cat 2"),
             2 => array(id=>3,name=>"cat 1"));

print_r(search($arr, 'name', 'cat 1'));

输出:

Array
(
    [0] => Array
        (
            [id] => 1
            [name] => cat 1
        )

    [1] => Array
        (
            [id] => 3
            [name] => cat 1
        )

)

如果效率很重要,你可以编写它,以便所有递归调用将其结果存储在同一个临时数组中,而不是将数组合并在一起,如下所示:$results

function search($array, $key, $value)
{
    $results = array();
    search_r($array, $key, $value, $results);
    return $results;
}

function search_r($array, $key, $value, &$results)
{
    if (!is_array($array)) {
        return;
    }

    if (isset($array[$key]) && $array[$key] == $value) {
        $results[] = $array;
    }

    foreach ($array as $subarray) {
        search_r($subarray, $key, $value, $results);
    }
}

关键是,通过引用而不是按值获取其第四个参数;& 符号至关重要。search_r&

仅供参考:如果你有一个旧版本的PHP,那么你必须在调用中指定传递引用部分,而不是在其声明中。也就是说,最后一行变为 。search_rsearch_r($subarray, $key, $value, &$results)


答案 2

那么SPL版本呢?这将为您节省一些输入:

// I changed your input example to make it harder and
// to show it works at lower depths:

$arr = array(0 => array('id'=>1,'name'=>"cat 1"),
             1 => array(array('id'=>3,'name'=>"cat 1")),
             2 => array('id'=>2,'name'=>"cat 2")
);

//here's the code:

    $arrIt = new RecursiveIteratorIterator(new RecursiveArrayIterator($arr));

 foreach ($arrIt as $sub) {
    $subArray = $arrIt->getSubIterator();
    if ($subArray['name'] === 'cat 1') {
        $outputArray[] = iterator_to_array($subArray);
    }
}

很棒的是,基本上相同的代码将通过使用RecursiveDirectoryIterator而不是RecursiveArrayIterator为您迭代目录。SPL是roxor。

关于SPL的唯一缺点是它在网络上的记录很糟糕。但是有几本PHP书籍详细介绍了一些有用的细节,特别是Pro PHP;你也可以谷歌获取更多信息。