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

我有各种各样的数组将包含

story & message 

要不就

 story 

我将如何检查数组是否包含故事和消息? array_key_exists()仅查找数组中的单个键。

有没有办法做到这一点?

如果你只有两个键来检查(就像在原来的问题中一样),调用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); } 

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

 <?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! } 

令人惊讶的array_keys_exist不存在? 在此期间,留下一些空间来找出这一共同任务的单行expression式。 我正在考虑一个shell脚本或另一个小程序。

注意:以下每个解决scheme都使用php 5.4+中提供的简洁数组声明语法

array_diff + array_keys

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

(帽子提示给金Stacks )

这个方法是我find的最简单的方法。 array_diff()返回参数1中存在的参数1中的项目数组。 因此,一个空数组表示find了所有的键。 在PHP5.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()使用callback来迭代数组以达到一个值。 通过提供我们感兴趣的$initial in的$initial值的键,然后移除在源中find的键,如果find所有键,我们可以期望以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解决scheme更容易编写,但稍微编辑一点点。 array_filter也是一个迭代callback,它允许你通过在callback中返回true(复制项目到新数组)或false(不复制)来创build一个过滤数组。 gotchya是你必须改变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 } 

在我看来,最简单的方法是:

 $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 ) 

这也允许检查哪些键准确地丢失。 这对于error handling可能是有用的。

那这个呢:

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

只有两者都不为null时才返回true

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

上面的解决scheme很聪明,但很慢。 使用isset的简单foreach循环比array_intersect_key解决scheme快两倍以上。

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

(对于1000000次迭代,344ms vs 768ms)

如果你有这样的事情:

 $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()几乎可以做同样的事情,除非被testing的值是NULL:

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

另外isset允许一次检查多个variables:

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

现在,为了优化testing设置的东西,你最好使用这个“如果”:

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

还有一个解决scheme:

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

这是我写给自己在课堂上使用的function。

 <?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。 如果你正在寻找至less一个键的匹配,让我知道,所以我可以提供另一个function。

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

尝试这个

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

这不行吗?

 array_key_exists('story', $myarray) && array_key_exists('message', $myarray) 
 <?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)); 

我不知道,如果它是坏主意,但我使用非常简单的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]); } } 
 // 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; } 
 $myArray = array('key1' => '', 'key2' => ''); $keys = array('key1', 'key2', 'key3'); $keyExists = count(array_intersect($keys, array_keys($myArray))); 

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

这样的东西可以使用

 //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,如果你想要search的值是不同的,你可以改变。

这个解决scheme可能不是有效的,但它的工作原理!

更新

在一个胖子function:

  /** * 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); 

希望这可以帮助 :)

希望这可以帮助:

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