I have an array of items on which I would like to apply search function. I am considering sorting the array and simply applying binary search for now as it need not be too complex, however if I run into problems I'll try other methods.
My question is; what is the search algorithm used in the array_search()? If it is indeed binary search I can use that.
PHP performs a linear search - here's the source
It has to be sequential search, because the array might not be sorted.
If you need to search an array often, use array_flip to convert it to an associative array where the values become the keys. Looking up keys in an array is a hash lookup.
It isn't a binary search.... it simply loops through the array until it finds the first matching element.... the internal equivalent of
foreach($haystack as $key => $value) {
if ($value == $needle) {
return $key;
}
}
Though for a fast search alternative, a Trie might be better than a binary search
Related
I want to know if inbuilt PHP array functions such as array_diff, array_keys or array_values (in comparison to array_walk) iterate through each item or do they have an internal algorithm through which they do the computation in one go?
This is important when I want to learn how to optimise PHP scripts which handle 100,000 items.
For e.g. this method:
public function narrowDown($BigArray, $Column, $regex)
{
# narrowDown to focus on columns with similar data
$Column = array_column($BigArray, $Column);
$Search = preg_quote($regex, '~');
$Matched = preg_grep('~'.$Search.'~', array_combine(array_keys($BigArray), $Column));
# recreate rows by intersecting with specified keys
return array_intersect_key($BigArray, $Matched);
}
This method finds out similar rows in a specified column by regex in a multi-dimensional array.
The array has 18 columns and 100,000 items. I was thinking what should be the best way to optimise such methods.
Feel free to also advise if I should shift to a different programming language.
Yes, they iterate through all items, also calls and their results are not cached in any way.
So if you will call array function twice with exactly same input, all the work will be done twice.
Often I find myself with an array of keys to some other array and want to get the corresponding values. For example if I wanted to select a random subarray, the function array_rand($array) will return an array of random indices and I want to get the values. There are many examples other than this but the general problem (normally arising from functional programming style) is I have an array of keys and need the array of the corresponding values. Here is a wordy way of doing this but I was wondering if there were some shorter way to do this frequent task?
way 1:
$array_of_values = array();
foreach($array_of_indices as $index)
$array_of_values[] = $array_of_data[$index];
way 2:
function index_array($index) { return $array_of_data[$index]; }
$array_of_values = array_map("index_array", $array_of_indices);
way 3:
$array_of_values = array_intersect_key($array_of_data,
array_fill_keys($array_of_indices, ''));
I would expect that some single function to do this exists but after reading through the docs I couldn't find one. Anyone know a better way?
There is no function that will do this on its own, however there is a slightly simpler way than way 3
array_intersect_key($array_of_data, array_flip($array_of_keys));
I have this situation in PHP. I have an array that has these keys for example, wires-1, wires-2, wires-3. I need a function or way for my program to read these keys, and find that the common word is wires? How would that be accomplished in PHP? Thanks for your help.
Take a look at how an autocomplete's functionality works, this is similar to your approach.
I'm sure there's plenty of source codes for autocomplete on google
For the string value of every key in your array:
Throw away all non-alpha characters, i.e. leave only letters such that ctype_alpha($remaining_text) should return true.
Keep an array with the found words as keys, and their frequencies as values, as such:
$array = new array();
function found_word($word)
{ global $array;
if(!isset($array[$word])) { $array[$word] = 1; }
else { $array[$word]++; }
}
Only nicer ;)
Sort the array in reverse by using arsort($array);
$array now contains the most found words as its first elements.
you would have to create every possible suffix of every string you have.
create a map for every suffix you found
count the occurence of every suffix in your string array
you can modify the performance with f.ex. limiting the suffix length
I am wondering if there are any classes for parsing PHP arrays in the general sense that you are looking back and forth over elements matching search patterns.
For example, lets say that If element "xyz" was found then I want to search backwards through the array until element "abc" or "cba" is found (or X number of steps backward is reached).
So I'm not sure how to describe this other than "regex for arrays". Does anyone know of any classes for this? My goal is to find data patterns in arrays that contain elements indexed in a certain order.
The standard array functions in PHP should get you pretty close: (assuming your array is $arr)
$key = array_search("xyz", $arr, true);
if($key != false){
$subset = array_slice($arr, 0, $key);
$search2 = array_search("abc", $subset, true);
}
If you want to search backwards (formally, backwards) you can do so by reversing the array before searching it with array_reverse, and if you want to set a limit on steps backwards you can make a smaller slice.
array_search
array_slice
Is there a php function that someone can use to automatically detect if an array is an associative or not, apart from explictly checking the array keys?
My short answer: YES
Quicker and easier, IF you make the assumption that a "non-associative array" is indexed starting at 0:
if ($original_array == array_values($original_array))
quoted from the official site:
The indexed and associative array
types are the same type in PHP,
So the best solution I can think of is running on all the keys, or using array_keys,implode,is_numeric
function is_associative_array($array) {
return (is_array($array) && !is_numeric(implode("", array_keys($array))));
}
Testing the keys works well.
Check out the discussions at is_array.
Short answer: no.
Long answer: Associative and indexed arrays are the same type in PHP. Indexed arrays are a subset of associative arrays where:
The keys are only integers;
They range from 0 to N-1 where N is the size of the array.
You can try and detect that if you want by using array_keys(), a sort and comparison with a range() result.