I want to avoid scanning the array twice. Something like TryGetValue in C#.
-
@JohnConde You mean write my own function with a for loop? – richard Dec 03 '13 at 18:58
-
1Just get the value. And then check to see if you got anything. – jszobody Dec 03 '13 at 18:58
-
5use array_key_exists() and if it does use the key to get the value. That's it. – John Conde Dec 03 '13 at 18:58
-
1short if : isset($array[$key)?$array[$key]:null; – ka_lin Dec 03 '13 at 19:00
-
1I want to avoid errors/warnings (i.e. your "just get the value and see if I got anything" suggestion) and I want to avoid scanning the array twice (check for key, and then get the value with the key). – richard Dec 03 '13 at 19:13
-
If the array is addressed by integer index, and contains only consecutive values, meeting the criteria for a plain ordered array, only a bounds check is performed, no scan happens. If the array is hash-based, as bucket lookup is performed, possibly twice. There may be some internal iterator or cache state that arrays hold behind the scene, though. See my answer below. – TylerY86 Nov 29 '15 at 05:37
-
@jszobody gave the best answer in a comment above - I've [added an answer](https://stackoverflow.com/a/56039491/199364) that expands on that. – ToolmakerSteve May 08 '19 at 11:25
3 Answers
No, there isn't a built-in function that does what you want. However, it's not hard to write a new one:
function tryGetValue($array, $key) {
return (array_key_exists($key, $array)) ? $array[$key] : NULL;
}
Example usage:
$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
![](../../users/profiles/1438393.webp)
- 70,371
- 17
- 120
- 139
-
2
-
@RichardDesLonde: Why do you need to scan the array twice? As the function name suggests, this will check if the given key exists in the array and outputs if it does. – Amal Murali Dec 03 '13 at 19:14
-
2I don't need to scan the array twice. In your function you first check if the key exists (1st scan) and then you get the value with $array[$key] (2nd scan). For performance, I want to avoid scanning twice. – richard Dec 03 '13 at 19:15
-
@RichardDesLonde: It doesn't scan the array twice. It simply checks if the given key exists in the array, and then retrieves the corresponding value. – Amal Murali Dec 03 '13 at 19:17
-
3
-
1
-
@RichardDesLonde: As I said, I edited the above comment to add more clarity. `It doesn't scan the array twice. It simply checks if the given key exists in the array, and then retrieves the corresponding value.` – Amal Murali Dec 03 '13 at 19:22
-
1You don't understand. HOW does the php function `array_key_exists` check if the key exists??? It SCANS THE ARRAY. – richard Dec 03 '13 at 19:23
-
1As explained in [this](http://stackoverflow.com/questions/16675753/php-fastest-way-to-handle-undefined-array-key) similar question, yes: it requires 2 lookup in the B-TREE: One to check existence, another to retrieve value. – T30 Aug 02 '16 at 12:59
@jszobody gave the best answer in a comment on the question .. seems to have been overlooked. Expanding on his comment:
What do you want to return, if the array key doesn't exist?
If null
, then the answer is "just do it":
@$array[$key]
("@" suppresses warning.)
If something else, and you don't store null values in array - so you don't ever want null
to be returned - then the answer is
@$array[$key] ?? $YourDefaultValue
That is, in php, it isn't necessary to pre-test whether a key exists. Unless your design BOTH 1) allows storing of null
values in the array, AND 2) wants a default other than null
. If both of these conditions are true, then you would need to explicitly test whether the key exists, using array_key_exists
.
![](../../users/profiles/199364.webp)
- 5,893
- 8
- 67
- 145
-
Just don't promote bad practice. :) https://stackoverflow.com/questions/136899/suppress-error-with-operator-in-php – TylerY86 Jul 22 '20 at 03:00
Check these microbenchmarks I created on 3v4l.
Here are the functions.
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();
}
It depends on if you care about null, and what version of PHP you're using.
Looks like the compilers try to optimize toward the isset and array_key_exists operations, at least for small arrays. This might imply that arrays have their own internal iterator state for this and similar purposes.
Interestingly, you can combine isset and array_key_exists (see tryGetValue3) and come out ahead sometimes.
This isn't a fully appropriate benchmark, as there are no null existing keys defined in the test array. Feel free to expand on the example. :)
![](../../users/profiles/2879498.webp)
- 3,609
- 13
- 28
-
Note that if the default value you want is `null`, it isn't necessary to do any of the above, so no need to call a function: its as simple as: [`@$array[$key]`](https://stackoverflow.com/a/56039491/199364). – ToolmakerSteve Jul 18 '20 at 00:29