如何检查多维数组中任意子数组的特定键是否存在特定值?

78

我需要在一个多维数组中搜索任意一个索引子数组中的特定值。

换句话说,我需要检查多维数组中的单个列是否存在某个值。 如果该值存在于多维数组中的任何位置,则返回true,否则返回false

$my_array = array(    
    0 =>  array(  
        "name"   => "john",  
        "id"    =>  4  
    ),  
    1   =>  array(  
        "name" =>  "mark",  
        "id" => 152  
    ), 
    2   =>  array(  
        "name" =>  "Eduard",  
        "id" => 152  
    )
);

我想知道检查数组$my_array是否包含键为"id"的值的最快和最有效的方法。例如,如果在多维数组中任何位置有id => 152,我希望返回true


如何获取找到的ID的关键数字。例如,如果我们搜索“id = 152”,结果将是“1”、“2”。@mickmackusa,@Rob - manas paul
嗨@mickmackusa,你能否帮我处理上述数组?另外,array_filter()foreach更快速地搜索吗?因为我需要在一个较大的数组中搜索相同的键。 - manas paul
@manas 我猜你想要这个。请删除你在页面上散布的所有其他评论。如果你想要多个值,只需不返回或中断即可。https://dev59.com/r3RA5IYBdhLWcg3wtwSe#16439674 - mickmackusa
18个回答

0
你可以创建一个子数组队列并循环每个子数组:
function existsKeyValue($myArray, $key, $value) {
    $queue = [$myArray]; //creating a queue of a single element, which is our outermost array

    //when we reach the count of the queue we looped all inner loops as well and failed to find the item
    for ($index = 0; $index < count($queue); $index++) {
        //Looping the current array, finding the key and the value
        foreach ($queue[$index] as $k => &$v) {
            //If they match the search, then we can return true
            if (($key === $k) && ($value === $v)) {
                return true;
            }
            //We need to make sure we did not already loop our current array to avoid infinite cycles
            if (is_array($v)) $queue[]=$v;
        }
    }
    return false;
}

$my_array = array(    
    0 =>  array(  
        "name"   => "john",  
        "id"    =>  4  
    ),  
    1   =>  array(  
        "name" =>  "mark",  
        "id" => 152  
    ), 
    2   =>  array(  
        "name" =>  "Eduard",  
        "id" => 152  
    )
);

echo var_dump(existsKeyValue($my_array, 'id', 152));


0

我不知道这对性能是好还是坏,但这里有一个替代方案:

$keys = array_map(function($element){return $element['id'];}, $my_array);
$flipped_keys = array_flip($keys);
if(isset($flipped_keys[40489]))
{
    // true
}

1
你可能也会对 array_column 感兴趣 https://php.net/array_column - hakre
我看到很多人建议这样做,我自己也尝试过但一直没能让它起作用,直到我看到了Manuel的代码。$key = array_search(40489, array_column($userdb, 'uid'));虽然我已经找到了解决方案,但我还是想分享一下。array_searcharray_column的组合非常完美。 - Marcus
array_column和array_flip的作用是相同的。这只是一个提示,供您参考。FYI,可以用array_column替换array_map部分,其余部分保持不变。个人认为不应该将其与array_search结合使用,而是像您使用array_flip一样。 - hakre

0

在以下示例中,只需使用array_column

$my_array = [
    [
        "name"  => "john",  
        "id"    =>  4  
    ],  
    [
        "name"  =>  "mark",  
        "id"    => 152  
    ], 
    [
        "name"  =>  "Eduard",  
        "id"    => 152  
    ]
];
var_dump(in_array(152, array_column($my_array, 'id'))); // true

-1

这个答案有多个问题,所以并不可行。在发布前请测试您的代码。 - mickmackusa

-1

尝试使用下面的代码。它应该适用于任何类型的多维数组搜索。

在这里你可以看到实时演示示例

function multi_array_search($search_for, $search_in) {
    foreach ($search_in as $element) {
        if ( ($element === $search_for) ){
            return true;
        }elseif(is_array($element)){
            $result = multi_array_search($search_for, $element);
            if($result == true)
                return true;
        }
    }
    return false;
}

请注意,使用递归不仅是不必要的开销,而且对第一级元素进行了不必要的检查。这证明了递归对于此问题是一个糟糕的选择。https://3v4l.org/Aua2W - mickmackusa

-1

你只需要使用两个参数即可

function whatever($array, $val) {
    foreach ($array as $item)
        if (isset($item) && in_array($val,$item))
            return 1;
    return 0;
}

在这个上下文中,isset($item) 没有太多意义。 - mickmackusa

-2
function checkMultiArrayValue($array) {
        global $test;
        foreach ($array as $key => $item) {

            if(!empty($item) && is_array($item)) {
                checkMultiArrayValue($item);
            }else {
                if($item)
                 $test[$key] = $item;

            }
        }
        return $test;   
    }

 $multiArray = array(    
                0 =>  array(  
                      "country"   => "",  
                      "price"    => 4,  
                      "discount-price" => 0,  
               ),);

$test = checkMultiArrayValue($multiArray);
echo "<pre>"
print_r($test);

将返回具有索引和值的数组


这个任务不适合使用递归技术。仅有代码的答案对于教育/赋能未来成千上万的研究人员几乎没有帮助。当你发布一个答案时,一定要用简单易懂的英语解释它是如何工作的,并且相比其他答案在这个特定问题上有哪些优势。 - mickmackusa

-3
我编写了以下函数,以确定多维数组是否部分包含某个值。
function findKeyValue ($array, $needle, $value, $found = false){
    foreach ($array as $key => $item){
        // Navigate through the array completely.
        if (is_array($item)){
            $found = $this->findKeyValue($item, $needle, $value, $found);
        }

        // If the item is a node, verify if the value of the node contains
        // the given search parameter. E.G.: 'value' <=> 'This contains the value'
        if ( ! empty($key) && $key == $needle && strpos($item, $value) !== false){
            return true;
        }
    }

    return $found;
}

像这样调用函数:

$this->findKeyValue($array, $key, $value);

1
没有必要为这个任务使用递归。输入数组只有两层深度。这是不必要的复杂化,不应该用于这个问题。 - mickmackusa

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