我想避免扫描数组两次。类似于C#中的TryGetValue。
不,没有一个内置函数可以满足您的需要。然而,写一个新的并不难:
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
更新
这不是推荐的做法。因为@
会抑制该表达式中的所有异常。
然而,AFAIK,这是满足OP规定标准的唯一有效方法(见对问题的评论):
我希望避免出现错误/警告,并且我希望避免扫描阵列两次。
推荐的做法可以在Amit的回答中看到。
也就是说,不要"微优化";您的代码。不要那么担心";扫描阵列两次";。编写干净、健壮的代码。稍后,如果测试发现性能问题,则评估如何提高性能。
Do处理错误和意外情况(异常)。
原始答案
@jszobody在对这个问题的评论中给出了答案。扩展他的评论:
如果数组键不存在,您希望返回什么?
如果null
就这么做":
@$array[$key]
("@"抑制警告。)
如果有其他内容,并且您不在数组中存储null值,因此您永远不希望返回null
,则此代码变为:
@$array[$key] ?? $YourDefaultValue
除非您的设计BOTH 1)允许在数组中存储null
值,否则AND 2)需要null
以外的默认值。如果这两个条件都为true,则需要使用array_key_exists
显式测试密钥是否存在。
检查我在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),有时也会脱颖而出。
这不是一个完全合适的基准测试,因为在测试数组中没有定义空的现有键。请随意扩展示例。:)