可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have a variety of arrays that will either contain
story & message
or just
story
How would I check to see if an array contains both story and message? array_key_exists()
only looks for that single key in the array.
Is there a way to do this?
回答1:
If you only have 2 keys to check (like in the original question), it's probably easy enough to just call array_key_exists()
twice to check if the keys exists.
if (array_key_exists("story", $arr) && array_key_exists("message", $arr)) {
// Both keys exist.
}
However this obviously doesn't scale up well to many keys. In that situation a custom function would help.
function array_keys_exists(array $keys, array $arr) {
return !array_diff_key(array_flip($keys), $arr);
}
回答2:
Here is a solution that's scalable, even if you want to check for a large number of keys:
<?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!
}
回答3:
Surprisingly array_keys_exist
doesn't exist?! In the interim that leaves some space to figure out a single line expression for this common task. I'm thinking of a shell script or another small program.
Note: each of the following solutions use concise […]
array declaration syntax available in php 5.4+
array_diff + array_keys
if (0 === count(array_diff(['story', 'message', '…'], array_keys($source)))) {
// all keys found
} else {
// not all
}
(hat tip to Kim Stacks)
This approach is the most brief I've found. array_diff()
returns an array of items present in argument 1 not present in argument2. Therefore an empty array indicates all keys were found. In php 5.5 you could simplify 0 === count(…)
to be simply 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
}
Harder to read, easy to change. array_reduce()
uses a callback to iterate over an array to arrive at a value. By feeding the keys we're interested in the $initial
value of $in
and then removing keys found in source we can expect to end with 0 elements if all keys were found.
The construction is easy to modify since the keys we're interested in fit nicely on the bottom line.
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
}
Simpler to write than the array_reduce
solution but slightly tricker to edit. array_filter
is also an iterative callback that allows you to create a filtered array by returning true (copy item to new array) or false (don't copy) in the callback. The gotchya is that you must change 2
to the number of items you expect.
This can be made more durable but verge's on preposterous readability:
$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:
It seems to me, that the easiest method by far would be this:
$required = array('a','b','c','d');
$values = array(
'a' => '1',
'b' => '2'
);
$missing = array_diff_key(array_flip($required), $values);
Prints:
Array(
[c] => 2
[d] => 3
)
This also allows to check which keys are missing exactly. This might be useful for error handling.
回答5:
The above solutions are clever, but very slow. A simple foreach loop with isset is more than twice as fast as the array_intersect_key
solution.
function array_keys_exist($keys, $array){
foreach($keys as $key){
if(!array_key_exists($key, $array))return false;
}
return true;
}
(344ms vs 768ms for 1000000 iterations)
回答6:
What about this:
isset($arr['key1'], $arr['key2'])
only return true if both are not null
if is null, key is not in array
回答7:
If you have something like this:
$stuff = array();
$stuff[0] = array('story' => 'A story', 'message' => 'in a bottle');
$stuff[1] = array('story' => 'Foo');
You could simply count()
:
foreach ($stuff as $value) {
if (count($value) == 2) {
// story and message
} else {
// only story
}
}
This only works if you know for sure that you ONLY have these array keys, and nothing else.
Using array_key_exists() only supports checking one key at a time, so you will need to check both seperately:
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()
returns true if the key is present in the array, but it is a real function and a lot to type. The language construct isset()
will almost do the same, except if the tested value is NULL:
foreach ($stuff as $value) {
if (isset($value['story']) && isset($value['message']) {
// story and message
} else {
// either one or both keys missing
}
}
Additionally isset allows to check multiple variables at once:
foreach ($stuff as $value) {
if (isset($value['story'], $value['message']) {
// story and message
} else {
// either one or both keys missing
}
}
Now, to optimize the test for stuff that is set, you'd better use this "if":
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:
One more solution in the collection:
if (!array_diff(['story', 'message'], array_keys($array))) {
// OK: all keys are in the $array
} else {
// FAIL: not all keys found
}
回答9:
This is the function I wrote for myself to use within a class.
<?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 />";
}
I am assuming you need to check for multiple keys ALL EXIST in an array. If you are looking for a match of at least one key, let me know so I can provide another function.
Codepad here http://codepad.viper-7.com/AKVPCH
回答10:
try this
$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:
Hope this helps:
function array_keys_exist($searchForKeys = array(), $inArray = array()) {
$inArrayKeys = array_keys($inArray);
return count(array_intersect($searchForKeys, $inArrayKeys)) == count($searchForKeys);
}
回答12:
Does this not work?
array_key_exists('story', $myarray) && array_key_exists('message', $myarray)
回答13:
<?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;
}
//run demo
$key = 'a,b,c';
$array = array('a'=>'aaaa','b'=>'ccc','c'=>'eeeee');
var_dump( check_keys_exists($key, $array));
回答14:
I am not sure, if it is bad idea but I use very simple foreach loop to check multiple array key.
// 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]);
}
}
回答15:
// 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;
}
回答16:
$myArray = array('key1' => '', 'key2' => '');
$keys = array('key1', 'key2', 'key3');
$keyExists = count(array_intersect($keys, array_keys($myArray)));
Will return true, because there are keys from $keys array in $myArray
回答17:
Something as this could be used
//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;
Note the check against 2, if the values you want to search is different you can change.
This solution may not be efficient, but it works!
Updates
In one fat 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)));
}
So for example with this:
$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);
Hope this helps :)
回答18:
This is old and will probably get buried, but this is my attempt.
I had an issue similar to @Ryan. In some cases, I needed to only check if at least 1 key was in an array, and in some cases, all needed to be present.
So I wrote this function:
/**
* 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;
}
This was a lot easier than having to write multiple ||
and &&
blocks.