我有各种不同的数组,这些数组可能会包含:
story & message
或者只是。story
我该如何检查一个数组是否同时包含“story”和“message”?array_key_exists()
函数只能检查单个键是否存在于数组中。
有没有其他方法可以实现?
以下是一种可扩展的解决方案,即使您需要检查大量密钥也可以使用:
<?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!
}
$ok = true;
foreach( $required as $field ) {
if( !array_key_exists( $field, $data ) )
$ok = false;
}
- Ozhreturn empty(array_intersect($keys, array_keys($array)));
。 - Mei Gwilym> 0
而不是=== count($required)
。 - CPHPython> 0
或 !empty(...)
-- 只需将返回的数组作为真值/假值进行评估。 if (array_intersect_key(array_flip($required), $data)) {
- mickmackusaarray_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);
}
$keys
包含一个不在$arr
中的元素和另一个在其中的元素,!array_diff_key
将返回空值false
(3v4l示例)。请注意保持原文意思,同时使翻译内容通俗易懂。 - CPHPython!array_diff($keys, array_keys($array));
让代码更易读,因为这样就不需要用到那些array_flip
函数来计算差异了。 - moopet令人惊讶的是,array_keys_exist
函数并不存在?!在这个暂时的空缺中,可以考虑为这个常见任务找到一个单行表达式。我正在考虑一个shell脚本或另一个小程序。
注意:以下每个解决方案都使用php 5.4+中可用的简洁的[...]
数组声明语法
if (0 === count(array_diff(['story', 'message', '…'], array_keys($source)))) {
// all keys found
} else {
// not all
}
感谢Kim Stacks的贡献。
这是我发现的最简洁的方法。 array_diff()
会返回一个包含参数1中存在但参数2中不存在的项目的数组。因此,空数组表示找到了所有键。在php 5.5中,您可以将0 === count(…)
简化为empty(…)
。
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个元素,如果所有键都被找到。
该结构易于修改,因为我们感兴趣的键很好地适合于底部行。
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
}
另外还有一个可能的解决方案:
if (!array_diff(['story', 'message'], array_keys($array))) {
// OK: all the keys are in $array
} else {
// FAIL: some keys are not
}
在我看来,最简单的方法应该是这样的:
$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
)
这还可以检查确切缺少哪些键,对于错误处理可能会很有用。
上述解决方案虽然巧妙,但不必要地缓慢。对于少量键的简单foreach循环速度更快。
function array_keys_exist($keys, $array){
foreach($keys as $key){
if(!array_key_exists($key, $array)) {
return false;
}
}
return true;
}
false
进行过早返回时(在这种情况下,false
会覆盖 true
),所以对于我的需求来说,以下代码是有效的:foreach ($keys as $key) { if (array_key_exists($key, $array)) { return true; }} return false;
我的需求是,如果一个数组中的 任何
键存在于另一个数组中... - Geoff这是什么意思:
isset($arr['key1'], $arr['key2'])
只有两者都不为空才返回true
如果为空,则键不在数组中
$arr['key1']
或$arr['key2']
的值为null
,那么代码仍然会保留这个键。 - Xorifelseforeach
循环? - Xorifelseisset
函数按照我的意图工作,但现在我意识到你是对的,键仍然留在数组中,因此我的答案不正确,谢谢反馈。是的,我可以使用foreach
。 - David Dutkovsky$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
}
}
我经常使用类似这样的东西
$wantedKeys = ['story', 'message'];
$hasWantedKeys = count(array_intersect(array_keys($source), $wantedKeys)) > 0
$wantedValues = array_intersect_key($source, array_fill_keys($wantedKeys, 1))
count(...) >0
不是必要的。(bool) array_intersect(array_keys($source), $wantedKeys)
是相同的。非空数组为真值;空数组为假值。 - mickmackusa试一下
$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_intersect_key()
函数,将要验证的键名数组与待检查的数组进行比较。如果输出的长度与待检查的键名数组长度相同,则说明它们都存在。请注意保持原文意思不变,同时使翻译更加通俗易懂。 - Michael Berkowski["story & message" => "value"]
这样的吗?还是更像["story & message"]
? - GordonM