检查多维数组中是否存在特定的数组键 - PHP

31

我有一个多维数组,例如(这可以是很多层):

$array = Array ( 
    [21] => Array ( ) 
    [24] => Array ( 
        [22] => Array ( ) 
        [25] => Array ( 
            [26] => Array ( ) 
        ) 
    ) 
) 

我正在尝试循环遍历它,以查看是否存在特定的键:

$keySearch = 22; // key searching for

function findKey($array, $keySearch) {
    foreach ($array as $item){
        if (isset($item[$keySearch]) && false === findKey($item[$keySearch], $item)){
            echo 'yes, it exists';
        }
    }
}

findKey($array, $keySearch);

但它找不到任何东西。循环中有错误吗?


请查看此链接:https://dev59.com/o07Sa4cB1Zd3GeqP1CVt#2948985 - Sudhir Bastakoti
为什么不直接使用 array_key_exists() 函数呢? - Haddock-san
8个回答

53

array_key_exists()有帮助的

然后就像这样:

function multiKeyExists(array $arr, $key) {

    // is in base array?
    if (array_key_exists($key, $arr)) {
        return true;
    }

    // check arrays contained in this array
    foreach ($arr as $element) {
        if (is_array($element)) {
            if (multiKeyExists($element, $key)) {
                return true;
            }
        }

    }

    return false;
}

示例代码: http://codepad.org/GU0qG5su


46

我用了你的代码并进行了调整以使其起作用:

function findKey($array, $keySearch)
{
    foreach ($array as $key => $item) {
        if ($key == $keySearch) {
            echo 'yes, it exists';
            return true;
        } elseif (is_array($item) && findKey($item, $keySearch)) {
            return true;
        }
    }
    return false;
}

1
难道不应该将 "if (isset( $array[$key] ) )" 改为 "if( is_array( $array[$key] ) )" 吗?显然,$key 在 $array 中已经设置了,因为 foreach 正在循环该数组。 - David Lawrence
如果(is_array($item))则查找关键字$keySearch。但是此调用的返回值已丢失。 - VolkerK
1
我已经编辑过以压缩if块。如果这是我的代码,我宁愿使用带有||的单个if。*需要使用括号作为逻辑。 - mickmackusa
顺便说一句,根据我的测试,为了使其正常工作,最好设置 === 运算符。谢谢! - Steven Yip
为了使其更完整,我建议还要检查$item是否为空。这可以避免一些未来可能出现的问题。 - tibelchior
如果一个被寻找的键指向 0null 或者空字符串,那么 $item 的“emptiness”可能是不相关的,因为 empty() 会给出错误的结果。或者你是指在对 $item 进行递归之前?如果数组为空,foreach() 将不会迭代任何内容。 - mickmackusa

13

这里有一个一行代码的解决方案:

echo strpos(json_encode($array), $key) > 0 ? "found" : "not found";

该函数将数组转换为包含JSON等效内容的字符串,然后将此字符串用作strpos()函数的haystack参数,并使用$key作为needle参数($key是要在JSON字符串中查找的值)。

可以通过以下方法有助于查看转换后的字符串:echo json_encode($array);

确保将needle参数用单引号和双引号括起来,因为JSON字符串中的名称/值对的名称部分将用双引号括起来。例如,如果在以下数组中查找22,则$key = '"22"'将在此数组中给出正确结果未找到

$array =
Array ( 
        21 => Array ( ), 
        24 => 
        Array ( 
            522 => Array ( ),
            25 =>
                Array ( 
                26 => Array ( ) 
            )
        )
    );

然而,如果单引号被省略,比如$key = "22",那么对于上面的数组,将会产生错误的found结果。

编辑: 另一个改进是搜索$key = '"22":';以防数组中存在"22"的值。例如:27 => "22" 此外,这种方法并非绝对可靠。如果数组中的任何值包含字符串'"22":',则可能会导致错误的found结果。


2
我会拒绝一个只在简单情况下有效,但在出现“特殊情况”时无法正常工作的解决方案。如果数组的值可能不包含所有任意值,因为这可能会干扰您的算法,那么该算法就是错误的。 - Nico Haase
不同意!!因为如果一个值等于搜索的键,它也会返回“found”。 - Jerry
1
这个解决方案仅适用于原帖中的基本、最小样本数据。数组中的值很容易导致这种技术产生错误的正面结果。我不赞成这种“hacky”解决方案。此答案没有尝试区分 JSON 负载中的“键”和“值”。 - mickmackusa

5
function findKey($array, $keySearch)
{
    // check if it's even an array
    if (!is_array($array)) return false;

    // key exists
    if (array_key_exists($keySearch, $array)) return true;

    // key isn't in this array, go deeper
    foreach($array as $key => $val)
    {
        // return true if it's found
        if (findKey($val, $keySearch)) return true;
    }

    return false;
}

// test
$array = Array ( 
    21 => Array ( 24 => 'ok' ),
    24 => Array ( 
        22 => Array ( 29 => 'ok' ),
        25 => Array ( 
            26 => Array ( 32 => 'ok' ) 
        )
    )
);

$findKeys = Array(21, 22, 23, 24, 25, 26, 27, 28, 29, 30);
foreach ($findKeys as $key)
{
    echo (findKey($array, $key)) ? 'found ' : 'not found ';
    echo $key.'<br>';
}

3
如果不存在则返回 false,如果存在则返回第一个实例;
function searchArray( array $array, $search )
{
    while( $array ) {
        if( isset( $array[ $search ] ) ) return $array[ $search ];
            $segment = array_shift( $array );
            if( is_array( $segment ) ) {
                if( $return = searchArray( $segment, $search ) ) return $return;
            }
        }
    }
    return false;
}

如果请求的键下存储的值是“false”,该怎么区分呢? ;) - Nico Haase

2

确定有一些错误,这大概是你想要的吗?(未经测试的代码):

$keySearch=22; // 要搜索的关键字

function findKey($array, $keySearch) 
{ 
    // check whether input is an array
    if(is_array($array)
    {
       foreach ($array as $item)
       {
         if (isset($item[$keySearch]) || findKey($item, $keysearch) === true)
          {
            echo 'yes, it exists';
            return true;
          }
       }
    }
}

2
该方法缺少一个明确的返回语句,用于处理键不存在的情况。 - Nico Haase
如果所查找的键与“null”值配对,则会生成错误的负面结果。 - mickmackusa

0

我已经修改了代码以返回搜索键的值:

function findKeyInArray($array, $keySearch, &$value)
{
    foreach ($array as $key => $item) {
        if ($key === $keySearch) {
            $value =  $item;
            break;
        } elseif (is_array($item)) {
            findKeyInArray($item, $keySearch,$value);
        }
    }
}
$timeZone = null;
findKeyInArray($request, 'timezone', $timeZone);

欢迎来到SO!请先看一下之前给出的其他答案。你的方法已经在那里提到了。为了保持网站的清晰和方便查找答案,我们尽量避免重复回答。 - ahuemmer

0

这里有一个解决方案,可以在任何维度的数组中查找并返回键的值。

function findValByKey($arr , $keySearch){
    $out = null;
    if (is_array($arr)){
        if (array_key_exists($keySearch, $arr)){
            $out = $arr[$keySearch];
        }else{
            foreach ($arr as $key => $value){
                if ($out = self::findValByKey($value, $keySearch)){
                    break;
                }
            }
        }
    }
    return $out;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接