【问题标题】:Is there a function to check if an array key exists, and get the value if it does, in one call?是否有一个函数可以在一次调用中检查数组键是否存在,如果存在则获取值?
【发布时间】:2013-12-03 18:56:38
【问题描述】:

我想避免两次扫描数组。类似TryGetValue in C#

【问题讨论】:

  • @JohnConde 你的意思是用 for 循环编写我自己的函数?
  • 只要获取价值。然后检查是否有任何东西。
  • 使用 array_key_exists() 如果它确实使用键来获取值。就是这样。
  • short if : isset($array[$key)?$array[$key]:null;
  • 我想避免错误/警告(即您的“只需获取值,看看我是否得到任何东西”的建议)并且我想避免扫描数组两次(检查密钥,然后获取键的值)。

标签: php arrays


【解决方案1】:

不,没有内置函数可以满足您的需求。不过,写一个新的并不难:

function tryGetValue($array, $key) {
    return (array_key_exists($key, $array)) ? $array[$key] : NULL;
}

示例用法:

$array = array('foo' => 'bar', 'baz', 'bak', 'bam');

var_dump(tryGetValue($array, 'foo'));   // string(3) "bar"
var_dump(tryGetValue($array, 's'));     // NULL
var_dump(tryGetValue($array, 2));       // string(3) "bam"
var_dump(tryGetValue($array, 4));       // NULL

【讨论】:

  • 那会扫描阵列两次吗?
  • 我不需要扫描阵列两次。在您的函数中,您首先检查密钥是否存在(第一次扫描),然后使用 $array[$key] (第二次扫描)获取值。为了性能,我想避免扫描两次。
  • 不扫描数组怎么知道key是否存在?
  • 它必须扫描数组以检查密钥是否存在。
  • 你不懂。 php函数array_key_exists如何检查key是否存在???它扫描阵列。
【解决方案2】:

更新

这不是推荐的做法。因为@ 抑制了该表达式中的所有异常。

但是,AFAIK,这是满足 OP 规定标准的唯一有效方法(请参阅问题评论):

我想避免错误/警告,并且我想避免两次扫描数组。

推荐做法见Amit's answer

也就是说,不要“微优化”您的代码。不要那么担心“扫描阵列两次”。编写干净、健壮的代码。稍后,如果测试发现性能问题,则评估如何提高性能。

处理错误和意外情况(异常)。


原始答案

@jszobody 在对该问题的评论中给出了答案。扩展他的评论:

如果数组键不存在,你想返回什么?

如果null,那么一种方法是“去做吧”:

@$array[$key]

("@" 禁止警告。)

如果有其他情况,并且您在数组中存储空值 - 所以您永远不希望返回 null - 那么这段代码将变为:

@$array[$key] ?? $YourDefaultValue

除非您的设计 1) 允许在数组中存储 null 值,并且 2) 需要除 null 以外的默认值。如果这两个条件都为真,那么您需要使用array_key_exists 显式测试密钥是否存在。

【讨论】:

  • 不要提倡不良做法。 :) stackoverflow.com/questions/136899/…
  • 请不要使用STFU运算符。
  • 我不同意上述 cmets - 但 OP 在评论中说 “我想避免错误/警告,我想避免两次扫描数组”。 AFAIK,这是 PHP 中有效满足这两个标准的唯一方法。实际上,结果是在该行代码期间完全抑制了异常。因此,我不建议做我所展示的 - 将其视为最后的手段。如果在较新的 PHP 版本中有任何方法可以安全地获得等效行为(C# 的 TryGetValue),那么请将其添加为问题的答案。无论如何,感谢您指出缺点。
【解决方案3】:

检查我创建的这些微基准 on 3v4l

这里是函数。

function tryGetValue1( $array, $key, Closure $default ) {
  return array_key_exists($key, $array)
    ? $array[$key] : $default();
}

function tryGetValue2( $array, $key, Closure $default ) {
  return ($value = @$array[$key]) !== null || array_key_exists($key, $array)
    ? $value : $default();
}

function tryGetValue3( $array, $key, Closure $default ) {
  return isset($array[$key]) || array_key_exists($key, $array)
    ? $array[$key] : $default();
}

function tryGetValueNotNull1( $array, $key, Closure $default ) {
  return ($value = @$array[$key]) !== null
    ? $value : $default();
}

function tryGetValueNotNull2( $array, $key, Closure $default ) {
  return isset($array[$key])
    ? $array[$key] : $default();
}

这取决于您是否关心 null,以及您使用的 PHP 版本。

看起来编译器尝试优化 isset 和 array_key_exists 操作,至少对于小数组。这可能意味着数组有自己的内部迭代器状态用于此目的和类似目的。

有趣的是,您可以将 isset 和 array_key_exists 结合起来(参见 tryGetValue3)并有时会领先。

这不是一个完全合适的基准测试,因为测试数组中没有定义空的现有键。随意扩展示例。 :)

【讨论】:

  • 请注意,如果你想要的默认值是null,则不需要执行上述任何操作,因此无需调用函数:它很简单:@$array[$key]
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-11
  • 1970-01-01
  • 2020-08-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多