PHP - checking key existence in an array - php

I have a file that contains a two denominational array:
<?php
return [
'key1' => 'value1' ,
'key2' => 'value2' ,
'key3' => 'value3'
];
?>
I need to test for the presence of an array key. I am wondering what is the most efficient way of doing so? What is going to give me the fastest response time? At present this file is 1.2 megs. It is going to grow to the range of 10 megs.
Ron

I think usually built-in functions is more efficient and fast. So, try to use php array_key_exist function in this way:
if (array_key_exists("key",$array))
return true;

Most efficient would be to use some better key-value store than array (SQLite, Redis, etc...). In all other ways you'll end up consuming memory, since array is initiated and memory is consumed in all cases.
If you don't mind consuming memory and are trying to be efficient on CPU side and each array member has value, then probably...
$array = include('myfile.php');
if (isset($array[$mykey])) {
echo "is set\n";
}
... is most efficient.

Related

Loop through nested arrays in PHP

I have a very complex array that I need to loop through.
Array(
[1] => Array(
[1] => ""
[2] => Array(
[1] => ""
[2] => Array(
[1] => ""
)
)
)
)
I can't use nested loops because this array could contain hundreds of nested arrays. Also, the nested ones could contain nested arrays too.
This array presents comments and replies, Where replies could contain more replies.
Any thoughts?
You could use a \RecursiveArrayIterator, which is part of the PHP SPL, shipped non-optional, with the PHP core.
<?php
$arr = [
'lvl1-A' => [
'lvl2' => [
'lvl3' => 'done'
],
],
'lvl1-B' => 'done',
];
function traverse( \Traversable $it ): void {
while ( $it->valid() ) {
$it->hasChildren()
? print "{$it->key()} => \n" and traverse( $it->getChildren() )
: print "{$it->key()} => {$it->current()}\n";
$it->next();
}
}
$it = new \RecursiveArrayIterator( $arr );
$it->rewind();
traverse( $it );
print 'Done.';
Run and play this example in the REPL here: https://3v4l.org/cGtoi
The code is just meant to verbosely explain what you can expect to see. The Iterator walks each level. How you actually code it is up to you. Keep in mind that filtering or flattening the array (read: transforming it up front) might be another option. You could as well use a generator and emit each level and maybe go with Cooperative Multitasking/ Coroutines as PHP core maintainer nikic explained in his blog post.
ProTip: Monitor your RAM consumption with different variants in case your nested Array really is large and maybe requested often or should deliver results fast.
In case you really need to be fast, consider streaming the result, so you can process the output while you are still working on processing the input array.
A last option might be to split the actual array in chunks (like when you are streaming them), therefore processing smaller parts.
The case is quite complex, as you have to loop, but you can't or don't want to for some reasons:
... that I need to loop through
and
I can't use nested loops because this array could contain hundreds of nested arrays
It means you have to either handle your data differently, as you can pack that huge amount of data to be processed later.
If for some reasons it's not an option, you can consider to:
split somehow this big array into smaller arrays
check how does it work with json_encode and parsing string with str_* functions and regex
Your question contains too many things we can't be sure e.g. what exactly these subarrays contain, can you ignore some parts of them, can you change the code that creates huge array in first place etc.
Assuming on the other hand that you could loop. What could bother you? The memory usage, how long it will take etc.?
You can always use cron to run it daily etc. but the most important is to find the cause why you ended up with huge array in the first place.

Using values as keys in arrays to reduce complexity when searching for items

Here is sometime I do a lot in PHP. Searching for a needle in a haystack.
$names = [
'Mike',
'John',
'Dave',
'Tony'
];
$gotDave = in_array('Dave', $names);
The runtime of in_array is O(n) where n is the number of elements.
I often setup my lookup data structure to look like this.
$names = [
'Mike' => true,
'John' => true,
'Dave' => true,
'Tony' => true
];
$gotDave = isset($names['Dave']);
The runtime is O(1) because in php the associative array is a hashmap.
Some questions:
should I do this? is this good practice?
is there a better value for the right hand ride
Yes, that's a great solution. In fact, that is how Sets are implemented in the core libraries of most programming languages - Off the top of my head, Python, Ruby, and Java do them this way. The Go language doesn't provide a Set, and just tells you to do what you've done.
I can't think of any reason to use any value other than true ```true``. It just makes sense.
you can use array_key_exists() to check for the key of the array, unlike in_array which checks for values
you will have to use array_key_exists() instead of isset() in your case

Memory effective Linear interpolation with PHP

I have a 1D array (XYData), e.g.
$TE = array(
"1"=>"20",
"2"=>"30",
"5"=>"50",
"10"=>"90"
)
I would like to create a memory effective PHP function which do the Linear interpolation of the passed X value and return the corresponding Y value. e.g.
calling function interpolate($TE,9.5)
then it should return 86
Is there any way to avoid the array search as the XYData set may be very long, say more then 100 points.
Thank you in advance!
No, you cannot avoid looking at your array. To make it more efficient you have to restructure your data. Do this by recursively looking for the middle, and then split it at that point into two parts. For your short example you would get this:
$TER = array("2 and lower" => array("1" => "20",
"2" => "30"),
"5 and higher" => array("5" => "50",
"8" => "100"));
No recursion is shown, and it really doesn't make any sense for such a small set of data, but when the dataset becomes large there's a clear advantage. It's basically a simple binary search tree.
But I have my doubts implementing it would be useful in this case. I'm not going to work it all out, you really should have 100.000 items or more to make this useful. If not, then just work through the array.

What is more performant, multiple Arrays or one Array containing multiple arrays?

What will be more performant and ressource friendlier?
To use
$array1=Array();
$array2=Array();
$array3=Array();
or:
$arr=Array();
$arr[] = Array();
$arr[] = Array();
$arr[] = Array();
And what is better to handle in the code when maintenance is required?
I have to handle about 2800 different arrays so the performance is very important.
Maintainability usually depends on what you're storing in the arrays and how you're accessing them...
If there are logical groupings/sets and you'd ever want to loop through the arrays ($array1, $array2, etc...) then make them nested associative arrays.
$Config = array(
'Database' => array(
'Host'=>"10.0.0.1",
'user'=>"root"
),
'API' => array(
'Endpoint'=>"http://example.com/"
),
);
If they're totally different, then it's really a judgement call
An array of arrays may be marginally lighter on memory but to be honest, with PHP the difference is going to be so small, it's not really worth wasting time worrying about until you get a performance bottleneck - and when you do, I suspect it won't be with how you declare your arrays
Kind of, if You'll have 1000 arrays, then it is probably better to have them all in one array, so using an array of arrays is better, then using 1000 variables each containing an array.
The second one will be slightly "better" since it doesn't create multiple variablenames.
Personally I wouldn't care and take the one that makes the most sense in your current situation. Style is often more important than performance, unless you have a compelling reason to focus on performance. (In which case another solution that PHP might be better.)

Modifing associative array keys & values (yes keys too). array_walk or foreach or something else

I am trying to modify an associative array eg.
array(
'key1' => 'val1',
'key2' => 'val2',
'key3' => 'val3'
)
to something like
array(
':key1' => 'val1xx',
':key2' => 'val2xx',
':key3' => 'val3xx'
// ^ colen
)
You may recognize I am trying to convert it into something I can use in PDOStatement::execute(). I dont currently need to modify the value, in this case. But will like to know just for knowledge
What can I use to do that? I am thinking foreach can do most things, but do functions like array_map or array_walk provide any benefits? Like performance? Or just looks different
There exists a big performance gap between the foreach and the array_map method. The fastest is the foreach construct. This construct can be five to six times as fast as an anonymous function, at least when there is not much to do within the loop. In most scenarios, the time it takes to iterate over the array is negligible compared to the time spend in the loop or anonymous function. So this performance difference does not really matter.For more information see link here.
$result = array();
foreach ($array as $key => $value)
$result[":$key"] = "{$value}xx";
Thariama's answer points to the performance gap between the for loop and array_map. It should also be pointed that there is no loop-free manner for modifying the keys in an array. You can modify the values in different loop-free ways (including array_map and array_walk) but not the keys.

Categories