如何检查是不是存在多个数组键

Posted

技术标签:

【中文标题】如何检查是不是存在多个数组键【英文标题】:How to check if multiple array keys exists如何检查是否存在多个数组键 【发布时间】:2012-10-21 14:21:47 【问题描述】:

我有各种各样的数组,它们将包含

story & message

或者只是

story

如何检查数组是否同时包含故事和消息? array_key_exists() 仅在数组中查找该单个键。

有没有办法做到这一点?

【问题讨论】:

如果“story”在任何一种情况下都会出现,听起来你真的只需要检查“message”。 使用array_intersect_key() 将您要验证的键数组与您正在检查的数组进行比较。如果输出的长度与要检查的键数组相同,则它们都存在。 Wyzard,我有其他包含消息但不包含故事的数组,但是那些具有故事或故事和消息的数组仅包含的其他键。谢谢 你在这里混淆了键和值吗?数组的格式是["story & message" => "value"] 还是更像["story & message"] 【参考方案1】:

这是一个可扩展的解决方案,即使您想检查大量密钥:

<?php

// The values in this arrays contains the names of the indexes (keys) 
// that should exist in the data array
$required = array('key1', 'key2', 'key3');

$data = array(
    'key1' => 10,
    'key2' => 20,
    'key3' => 30,
    'key4' => 40,
);

if (count(array_intersect_key(array_flip($required), $data)) === count($required)) 
    // All required keys exist!

【讨论】:

我想知道这被否决的原因.. afaik 这更快,因为 array_intersect_key 是用 C 实现的,你不需要循环 其实很聪明,做得很好——虽然有点难读。 谢谢 :) 奇怪的是 PHP 没有内置函数来执行此操作 - 这很常见。有大量的用户输入验证类可以做到这一点,但对于大多数用例来说,它的杀伤力太大 确实是聪明的解决方案,但它确实比简单的要慢(在我的盒子上慢约 50%):``` $ok = true; foreach( $required as $field ) if( !array_key_exists( $field, $data ) ) $ok = false; @Ozh 除了 array_key_exists 比 isset 慢【参考方案2】:

如果您只有 2 个要检查的键(如在原始问题中),只需调用两次 array_key_exists() 即可检查键是否存在。

if (array_key_exists("story", $arr) && array_key_exists("message", $arr)) 
    // Both keys exist.

但是,这显然不能很好地扩展到许多键。在这种情况下,自定义函数会有所帮助。

function array_keys_exists(array $keys, array $arr) 
   return !array_diff_key(array_flip($keys), $arr);

【讨论】:

如果人们认为其他解决方案更适合检查数组是否存在两个成员,那么他们一定不喜欢清晰可读的代码或性能:) 如果您需要的密钥相对较少,这可能是最简单的解决方案。如果它们是 20 或 30 之类的东西,if 将变得不可读。 @apokryfos 同意,但它确实回答了 OP 的问题。 @alex 唯一的问题是,如果$keys 包含一个不在$arr 中的元素,而另一个在其中,!array_diff_key 返回空 => false (3v4l example)... 我认为这可以通过使用!array_diff($keys, array_keys($array)); 使其更具可读性,因为在计算这些array_flips 时涉及的认知负担会少一些。【参考方案3】:

令人惊讶的是array_keys_exist 不存在?!在此期间留出一些空间来为这个常见任务找出一个单行表达式。我正在考虑一个 shell 脚本或另一个小程序。

注意:以下每个解决方案都使用 php 5.4+ 中可用的简洁 […] 数组声明语法

array_diff + array_keys

if (0 === count(array_diff(['story', 'message', '…'], array_keys($source)))) 
  // all keys found
 else 
  // not all

(给Kim Stacks的帽子提示)

这种方法是我发现的最简洁的方法。 array_diff() 返回参数 1 中存在的项目数组 not 存在于参数 2 中。因此,一个空数组表示找到了所有键。在 php 5.5 中,您可以将 0 === count(…) 简化为简单的 empty(…)

array_reduce + unset

if (0 === count(array_reduce(array_keys($source), 
    function($in, $key) unset($in[array_search($key, $in)]); return $in; , 
    ['story', 'message', '…'])))

  // all keys found
 else 
  // not all

更难阅读,更容易改变。 array_reduce() 使用回调来遍历数组以得到一个值。通过提供我们对$in$initial 值感兴趣的键,然后删除在源中找到的键,如果找到所有键,我们可以期望以 0 元素结尾。

结构很容易修改,因为我们感兴趣的键非常适合底线。

array_filter & in_array

if (2 === count(array_filter(array_keys($source), function($key)  
        return in_array($key, ['story', 'message']); 
    )))

  // all keys found
 else 
  // not all

array_reduce 解决方案编写起来更简单,但编辑起来有点棘手。 array_filter 也是一个迭代回调,允许您通过在回调中返回 true(将项目复制到新数组)或 false(不复制)来创建过滤数组。问题是您必须将2 更改为您期望的项目数。

这可以变得更耐用,但可读性很差:

$find = ['story', 'message'];
if (count($find) === count(array_filter(array_keys($source), function($key) use ($find)  return in_array($key, $find); )))

  // all keys found
 else 
  // not all

【讨论】:

小套装的差异可以忽略不计。如果您正在编写一个处理大量数据的库/框架,您可能应该对每个单元进行性能测试以发现瓶颈,而不是过早地进行优化。【参考方案4】:

在我看来,迄今为止最简单的方法是:

$required = array('a','b','c','d');

$values = array(
    'a' => '1',
    'b' => '2'
);

$missing = array_diff_key(array_flip($required), $values);

打印:

Array(
    [c] => 2
    [d] => 3
)

这也允许检查哪些键丢失了。这可能对错误处理很有用。

【讨论】:

这就是我来这里的目的!【参考方案5】:

另一种可能的解决方案:

if (!array_diff(['story', 'message'], array_keys($array))) 
    // OK: all the keys are in $array
 else 
   // FAIL: some keys are not

【讨论】:

【参考方案6】:

上述解决方案很聪明,但速度很慢。使用 isset 的简单 foreach 循环的速度是 array_intersect_key 解决方案的两倍多。

function array_keys_exist($keys, $array)
    foreach($keys as $key)
        if(!array_key_exists($key, $array))return false;
    
    return true;

(1000000 次迭代为 344 毫秒 vs 768 毫秒)

【讨论】:

isset 将返回 false 如果 ['key' => null] 并且有时您的数组具有空值。您应该使用 array_key_exists 代替 isset 我不得不在这里使用相反的值,因为false 过早返回(在这种情况下false 覆盖true)。所以,满足我需求的是foreach ($keys as $key) if (array_key_exists($key, $array)) return true; return false; 我的需求是如果一个数组中的any 键存在于另一个数组中...... 我不会在 100 万个键上调用 +/- 400 毫秒“非常慢”,但我只是人类!【参考方案7】:

如果你有这样的事情:

$stuff = array();
$stuff[0] = array('story' => 'A story', 'message' => 'in a bottle');
$stuff[1] = array('story' => 'Foo');

你可以简单地count():

foreach ($stuff as $value) 
  if (count($value) == 2) 
    // story and message
   else 
    // only story
  

这只有在你确定你只有这些数组键时才有效。

使用array_key_exists()只支持一次检查一个键,所以你需要分别检查:

foreach ($stuff as $value) 
  if (array_key_exists('story', $value) && array_key_exists('message', $value) 
    // story and message
   else 
    // either one or both keys missing
  

array_key_exists() 如果键存在于数组中,则返回 true,但它是一个真正的函数,需要输入很多内容。语言构造 isset() 几乎可以做同样的事情,除非测试值为 NULL:

foreach ($stuff as $value) 
  if (isset($value['story']) && isset($value['message']) 
    // story and message
   else 
    // either one or both keys missing
  

此外,isset 允许一次检查多个变量:

foreach ($stuff as $value) 
  if (isset($value['story'], $value['message']) 
    // story and message
   else 
    // either one or both keys missing
  

现在,要优化已设置内容的测试,您最好使用以下“如果”:

foreach ($stuff as $value) 
  if (isset($value['story']) 
    if (isset($value['message']) 
      // story and message
     else 
      // only story
    
   else 
    // No story - but message not checked
  

【讨论】:

【参考方案8】:

这个呢:

isset($arr['key1'], $arr['key2']) 

只有当两者都不为空时才返回真

如果为null,则key不在数组中

【讨论】:

如果$arr['key1']$arr['key2']的值为null,则code会,key依然存在。 我写了一个测试请看@Xorifelse test 如果我错了请纠正我。仅供参考:那时我只知道 PHP 5.6.* 版本,所以我只为它做了。 这段代码试图完成什么?为什么不只使用foreach 循环? 我想添加一个证明 isset 函数按我的意思工作,但现在我意识到你是对的,键仍然保留在数组中,因此我的答案不正确,谢谢回馈。是的,我可以使用它foreach【参考方案9】:

我经常使用这样的东西

$wantedKeys = ['story', 'message'];
$hasWantedKeys = count(array_intersect(array_keys($source), $wantedKeys)) > 0

或查找所需键的值

$wantedValues = array_intersect_key($source, array_fill_keys($wantedKeys, 1))

【讨论】:

【参考方案10】:

试试这个

$required=['a','b'];$data=['a'=>1,'b'=>2];
if(count(array_intersect($required,array_keys($data))>0)
    //a key or all keys in required exist in data
 else
    //no keys found
  

【讨论】:

【参考方案11】:

这是我为自己编写的用于在类中使用的函数。

<?php
/**
 * Check the keys of an array against a list of values. Returns true if all values in the list
 is not in the array as a key. Returns false otherwise.
 *
 * @param $array Associative array with keys and values
 * @param $mustHaveKeys Array whose values contain the keys that MUST exist in $array
 * @param &$missingKeys Array. Pass by reference. An array of the missing keys in $array as string values.
 * @return Boolean. Return true only if all the values in $mustHaveKeys appear in $array as keys.
 */
    function checkIfKeysExist($array, $mustHaveKeys, &$missingKeys = array()) 
        // extract the keys of $array as an array
        $keys = array_keys($array);
        // ensure the keys we look for are unique
        $mustHaveKeys = array_unique($mustHaveKeys);
        // $missingKeys = $mustHaveKeys - $keys
        // we expect $missingKeys to be empty if all goes well
        $missingKeys = array_diff($mustHaveKeys, $keys);
        return empty($missingKeys);
    


$arrayHasStoryAsKey = array('story' => 'some value', 'some other key' => 'some other value');
$arrayHasMessageAsKey = array('message' => 'some value', 'some other key' => 'some other value');
$arrayHasStoryMessageAsKey = array('story' => 'some value', 'message' => 'some value','some other key' => 'some other value');
$arrayHasNone = array('xxx' => 'some value', 'some other key' => 'some other value');

$keys = array('story', 'message');
if (checkIfKeysExist($arrayHasStoryAsKey, $keys))  // return false
    echo "arrayHasStoryAsKey has all the keys<br />";
 else 
    echo "arrayHasStoryAsKey does NOT have all the keys<br />";


if (checkIfKeysExist($arrayHasMessageAsKey, $keys))  // return false
    echo "arrayHasMessageAsKey has all the keys<br />";
 else 
    echo "arrayHasMessageAsKey does NOT have all the keys<br />";


if (checkIfKeysExist($arrayHasStoryMessageAsKey, $keys))  // return false
    echo "arrayHasStoryMessageAsKey has all the keys<br />";
 else 
    echo "arrayHasStoryMessageAsKey does NOT have all the keys<br />";


if (checkIfKeysExist($arrayHasNone, $keys))  // return false
    echo "arrayHasNone has all the keys<br />";
 else 
    echo "arrayHasNone does NOT have all the keys<br />";

我假设您需要检查数组中的多个键 ALL EXIST。如果您正在寻找至少一个键的匹配项,请告诉我,以便我提供其他功能。

这里是键盘http://codepad.viper-7.com/AKVPCH

【讨论】:

解决方案很好,但埋藏了一个不错的单行宝石:if (0 === count(array_diff(['key1','key2','key3'], array_keys($lookIn)))) // all keys exist else // nope 你写的是真的。我确实发现我的函数虽然冗长但更具可读性。当然,我可能弄错了。感谢您对我的回答发表评论。我学到了一些新东西。【参考方案12】:

希望这会有所帮助:

function array_keys_exist($searchForKeys = array(), $inArray = array()) 
    $inArrayKeys = array_keys($inArray);
    return count(array_intersect($searchForKeys, $inArrayKeys)) == count($searchForKeys); 

【讨论】:

【参考方案13】:

这是旧的,可​​能会被掩埋,但这是我的尝试。

我遇到了与@Ryan 类似的问题。在某些情况下,我只需要检查数组中是否至少有一个键,在某些情况下,所有 需要 都存在。

所以我写了这个函数:

/**
 * A key check of an array of keys
 * @param array $keys_to_check An array of keys to check
 * @param array $array_to_check The array to check against
 * @param bool $strict Checks that all $keys_to_check are in $array_to_check | Default: false
 * @return bool
 */
function array_keys_exist(array $keys_to_check, array $array_to_check, $strict = false) 
    // Results to pass back //
    $results = false;

    // If all keys are expected //
    if ($strict) 
        // Strict check //

        // Keys to check count //
        $ktc = count($keys_to_check);
        // Array to check count //
        $atc = count(array_intersect($keys_to_check, array_keys($array_to_check)));

        // Compare all //
        if ($ktc === $atc) 
            $results = true;
        
     else 
        // Loose check - to see if some keys exist //

        // Loop through all keys to check //
        foreach ($keys_to_check as $ktc) 
            // Check if key exists in array to check //
            if (array_key_exists($ktc, $array_to_check)) 
                $results = true;
                // We found at least one, break loop //
                break;
            
        
    

    return $results;

这比编写多个 ||&amp;&amp; 块要容易得多。

【讨论】:

【参考方案14】:

这不行吗?

array_key_exists('story', $myarray) && array_key_exists('message', $myarray)

【讨论】:

常量不能是数组... :) 当我不在我的超级代码检查自动完成 IDE 中编写时,我总是忘记 $。 =)【参考方案15】:
<?php

function check_keys_exists($keys_str = "", $arr = array())
    $return = false;
    if($keys_str != "" and !empty($arr))
        $keys = explode(',', $keys_str);
        if(!empty($keys))
            foreach($keys as $key)
                $return = array_key_exists($key, $arr);
                if($return == false)
                    break;
                
            
        
    
    return $return;

//运行演示

$key = 'a,b,c';
$array = array('a'=>'aaaa','b'=>'ccc','c'=>'eeeee');

var_dump( check_keys_exists($key, $array));

【讨论】:

【参考方案16】:

我不确定,如果这是个坏主意,但我使用非常简单的 foreach 循环来检查多个数组键。

// get post attachment source url
$image     = wp_get_attachment_image_src(get_post_thumbnail_id($post_id), 'single-post-thumbnail');
// read exif data
$tech_info = exif_read_data($image[0]);

// set require keys
$keys = array('Make', 'Model');

// run loop to add post metas foreach key
foreach ($keys as $key => $value)

    if (array_key_exists($value, $tech_info))
    
        // add/update post meta
        update_post_meta($post_id, MPC_PREFIX . $value, $tech_info[$value]);
    
 

【讨论】:

【参考方案17】:
// sample data
$requiredKeys = ['key1', 'key2', 'key3'];
$arrayToValidate = ['key1' => 1, 'key2' => 2, 'key3' => 3];

function keysExist(array $requiredKeys, array $arrayToValidate) 
    if ($requiredKeys === array_keys($arrayToValidate)) 
        return true;
    

    return false;

【讨论】:

【参考方案18】:
$myArray = array('key1' => '', 'key2' => '');
$keys = array('key1', 'key2', 'key3');
$keyExists = count(array_intersect($keys, array_keys($myArray)));

将返回 true,因为在 $myArray 中有来自 $keys 数组的键

【讨论】:

【参考方案19】:

可以使用的东西

//Say given this array
$array_in_use2 = ['hay' => 'come', 'message' => 'no', 'story' => 'yes'];
//This gives either true or false if story and message is there
count(array_intersect(['story', 'message'], array_keys($array_in_use2))) === 2;

注意对 2 的检查,如果您要搜索的值不同,您可以更改。

此解决方案可能效率不高,但确实有效!

更新

在一个 fat 函数中:

 /**
 * Like php array_key_exists, this instead search if (one or more) keys exists in the array
 * @param array $needles - keys to look for in the array
 * @param array $haystack - the <b>Associative</b> array to search
 * @param bool $all - [Optional] if false then checks if some keys are found
 * @return bool true if the needles are found else false. <br>
 * Note: if hastack is multidimentional only the first layer is checked<br>,
 * the needles should <b>not be<b> an associative array else it returns false<br>
 * The array to search must be associative array too else false may be returned
 */
function array_keys_exists($needles, $haystack, $all = true)

    $size = count($needles);
    if($all) return count(array_intersect($needles, array_keys($haystack))) === $size;
    return !empty(array_intersect($needles, array_keys($haystack)));


例如:

$array_in_use2 = ['hay' => 'come', 'message' => 'no', 'story' => 'yes'];
//One of them exists --> true
$one_or_more_exists = array_keys_exists(['story', 'message'], $array_in_use2, false);
//all of them exists --> true
$all_exists = array_keys_exists(['story', 'message'], $array_in_use2);

希望这会有所帮助:)

【讨论】:

【参考方案20】:

我通常使用一个函数来验证我的帖子,它也是这个问题的答案,所以让我发布它。

要调用我的函数,我会像这样使用 2 数组

validatePost(['username', 'password', 'any other field'], $_POST))

那么我的函数将如下所示

 function validatePost($requiredFields, $post)
    
        $validation = [];

        foreach($requiredFields as $required => $key)
        
            if(!array_key_exists($key, $post))
            
                $validation['required'][] = $key;
            
        

        return $validation;
    

这将输出这个

“必需”:[ “用户名”, “密码”, “任何其他领域” ]

所以这个函数所做的是验证并返回发布请求的所有缺失字段。

【讨论】:

【参考方案21】:
    $colsRequired   = ["apple", "orange", "banana", "grapes"];
    $data           = ["apple"=>"some text", "orange"=>"some text"];
    $presentInBoth  = array_intersect($colsRequired,array_keys($data));

    if( count($presentInBoth) != count($colsRequired))
        echo "Missing keys  :" . join(",",array_diff($colsRequired,$presentInBoth));
    else
        echo "All Required cols are present";

【讨论】:

欢迎来到 ***,您能否通过详细说明和描述代码来改进您的答案,并说明为什么此代码是一个解决方案。

以上是关于如何检查是不是存在多个数组键的主要内容,如果未能解决你的问题,请参考以下文章

检查是不是存在与正则表达式匹配的数组键

如何检查项目是不是存在于多个数组中

检查多维数组的任何子数组中的特定键是不是存在特定值

检查对象数组中是不是存在具有特定键值的对象

检查 JavaScript 对象中是不是存在键?

如何检查数组中是不是存在相同的键?