Indexing array with an array of keys Shorthand in PHP - php

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));

Related

Does array_values in PHP loop through all the items?

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.

php sort associative arrays by keys that those keys exist in other array

I have this array
$myArray=array(
'a'=>array('id'=>1,'text'=>'blabla1'),
'b'=>array('id'=>2,'text'=>'blabla2'),
'c'=>array('id'=>3,'text'=>'blabla3'),
'd'=>array('id'=>4,'text'=>'blabla4'),
);
and i want to sort the above array by the keys a,b,c,d, who exist in another array:
$tempArray=array('c','a','d','b');
How can I do that so the $myArray
looks like this:
$myArray=array(
'c'=>array('id'=>3,'text'=>'blabla3'),
'a'=>array('id'=>1,'text'=>'blabla1'),
'd'=>array('id'=>4,'text'=>'blabla4'),
'b'=>array('id'=>2,'text'=>'blabla2'),
);
thanks for helping me!
The simplest and likely most efficient way to do this is by iterating the array that holds the sort order and creating a new, sorted array:
$sorted = array();
foreach ($tempArray as $order) {
if (isset($myArray[$order])) {
$sorted[$order] = $myArray[$order];
}
}
print_r($sorted);
This works because associative arrays implicitly have an order of the order in which elements were added to the array.
See it working
EDIT
Any solution involving a sorting function will likely be much less efficient than this. This is because in order to do it you will need to use a function that takes a callback - this already has an implied overhead of the function call.
The sorting functions also work by comparing items, meaning that the complexity any of those solutions will be greater than that of this solution (the complexity of this is simply O(n)). Also, in order to derive the return value for the sorting function you would need to inspect the target array, finding the position of each of the keys being compared, for each comparison, adding even more complexity.

Creating an associative array from an array, based on the array - PHP

I have a unique issue that I have never heard of this being possible to do before:
So essentially I have a function that takes in a an array of arguments such as:
function someFunction(array $arguments){}
and gives me an array back as such:
array('option1', 'option2', 'options3', ...);
I then need to take that array and loop through it creating an associative array such as:
array('option1' => call_come_method('option1'), .... );
heres the kicker, you will never know how many arguments a user passes into the function, yet each one needs to created into a key=>value arrangement as seen above.
Now i did some research and I was told the $argv command in php, how ever where I am stumped is how to implement it in this case.
So if any one can give me any pointers I would be appreciative.
This is a lot easier than you think. First use array_flip to switch the array's keys and values.
$newArray = array_flip($arguments);
Then loop though it and call the method:
foreach($newArray as $key=>&$val){
$val = call_come_method($key);
}
The &, makes it a reference, so the array value is updated.
DEMO: http://codepad.org/giL1KPA3
UPDATE: You don't even need array_flip, you just need a for loop.
$newArray = array();
foreach($arguments as $val){
$newArray[$val] = call_come_method($val);
}
DEMO: http://codepad.org/AQ1gWrou
you will never know how many arguments a user passes into the function
FYI, you get to know it with func_get_args().
This way you don't need to provide your function with an $arguments parameter, but you just leave it empty.

Is it better to use Associative arrays or standard arrays in this situation?

I have a list of checkboxes with their labels that I'm outputting in a form. The html requirement is a bit more complicated so I'm going to loop through to make this less mundane.
However, I'm not sure if I use:
$array[] = array("Label1", "CheckboxHTML1");
$array[] = array("Label2", "CheckboxHTML2");
$array[] = array("Label3", "CheckboxHTML3");
$array[] = array("Label4", "CheckboxHTML4");
//output
foreach($array as $current)
{
//complicated html
echo "<label>$current[0]</label>$current[1]";
}
Or:
$array["Label1"] = "CheckboxHTML1";
$array["Label2"] = "CheckboxHTML2";
$array["Label3"] = "CheckboxHTML3";
$array["Label4"] = "CheckboxHTML4";
foreach($array as $key => $checkbox)
{
//complicated html
echo "<label>$key</label>$checkbox[1]";
}
Does one have any greater benefit over the other? I was worried with using associative arrays because some of the label strings are very long and I wasn't sure if this would cause any problems.
You won't have any issues as far as the length of the key. As a general rule of thumb, it's best to use associative arrays when you know you, as the developer, might want to access that data based upon its name in the future.
There is no limit to string size in PHP. String can be as large as 2GB.
I think it's ok to assume this applies for arrays to. I mean using string as key.
I guess you should go the way suits you best. I'm opting for associative array.
You should just do whatever is most natural in each case. Associative arrays exist so that you can efficiently retrieve items by key; if you intend to do that then use them.
It's true that almost certainly long keys will slightly impact performance when the array is constructed, but the definition of "very long" is not the same for humans and compilers.

Get arbitrary number of random elements from a php array in one line

I wanted to pull an arbitrary number of random elements from an array in php. I see that the array_rand() function pulls an arbitrary number of random keys from an array. All the examples I found online showed then using a key reference to get the actual values from the array, e.g.
$random_elements = array();
$random_keys = array_rand($source_array);
foreach ( $random_keys as $random_key ) {
$random_elements[] = $source_array[$random_key];
}
That seemed cumbersome to me; I was thinking I could do it more concisely. I would need either a function that plain-out returned random elements, instead of keys, or one that could convert keys to elements, so I could do something like this:
$random_elements = keys_to_elements(array_rand($source_array, $number, $source_array));
But I didn't find any such function(s) in the manual nor in googling. Am I overlooking the obvious?
What about usung array_flip? Just came to my mind:
$random_elements = array_rand(array_flip($source_array), 3);
First we flip the array making its values become keys, and then use array_rand.
An alternate solution would be to shuffle the array and return a slice from the start of it.
Or, if you don't want to alter the array, you could do:
array_intersect_key($source_array, array_combine(
array_rand($source_array, $number), range(1, $number)));
This is a bit hacky because array_intersect can work on keys or values, but not selecting keys from one array that match values in another. So, I need to use array_combine to turn those values into keys of another array.
You could do something like this, not tested!!!
array_walk(array_rand($array, 2), create_function('&$value,$key',
'$value = '.$array[$value].';'));

Categories