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

Rya*_*yan 75 php key

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

story & message
Run Code Online (Sandbox Code Playgroud)

or just

story
Run Code Online (Sandbox Code Playgroud)

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?

Erf*_*fan 183

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

<?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!
}
Run Code Online (Sandbox Code Playgroud)

  • 确实是聪明的解决方案,但它真的比我的盒子慢得多(比我的盒子快约50%):```$ ok = true; foreach($ required as $ field){if(!array_key_exists($ field,$ data))$ ok = false; } (11认同)

ale*_*lex 56

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.
}
Run Code Online (Sandbox Code Playgroud)

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);
}
Run Code Online (Sandbox Code Playgroud)

  • 如果人们认为其他解决方案更适合检查数组是否存在两个成员,则他们必须不喜欢清晰可读的代码或性能:) (3认同)
  • 我认为可以使用`!array_diff($ keys,array_keys($ array));`使其更具可读性,因为在处理这些array_flip时所涉及的认知负荷要少一些。 (3认同)
  • @alex唯一的问题是,如果`$ keys`包含**一个不在`$ arr`**中的元素而另一个元素在其中,`!array_diff_key`返回empty =>`false`([3v4l example] (https://3v4l.org/svno0))... (2认同)

Mar*_*Fox 32

令人惊讶的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
}
Run Code Online (Sandbox Code Playgroud)

(给Kim Stacks提示)

这种方法是我发现的最简短的方法.array_diff()返回参数1中存在于参数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
}
Run Code Online (Sandbox Code Playgroud)

更难阅读,易于改变.array_reduce()使用回调迭代数组以获得值.通过提供我们感兴趣的键的$initial值,$in然后删除源中找到的键,如果找到所有键,我们可以期望以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
}
Run Code Online (Sandbox Code Playgroud)

编写比array_reduce解决方案更简单,但编辑略有琐事.array_filter也是一个迭代回调,允许您通过在回调中返回true(复制项到新数组)或false(不复制)来创建过滤数组.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
}
Run Code Online (Sandbox Code Playgroud)

  • 小集合的差异可以忽略不计.如果您正在编写处理大量数据的库/框架,那么您应该对每个单元进行性能测试,以找出瓶颈,而不是过早地进行优化. (2认同)

Pet*_*lka 14

在我看来,到目前为止最简单的方法是:

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

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

$missing = array_diff_key(array_flip($required), $values);
Run Code Online (Sandbox Code Playgroud)

打印:

Array(
    [c] => 2
    [d] => 3
)
Run Code Online (Sandbox Code Playgroud)

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


Vas*_*ily 10

另一种可能的解决方案:

if (!array_diff(['story', 'message'], array_keys($array))) {
    // OK: all the keys are in $array
} else {
   // FAIL: some keys are not
}
Run Code Online (Sandbox Code Playgroud)


iau*_*ion 7

上述解决方案很聪明,但速度很慢.使用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;
}
Run Code Online (Sandbox Code Playgroud)

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