I don't know is there such thing as dynamic array_intersect? Anyway i have 3 arrays ( later there will be much more arrays)
$kaID = array();
$tgID = array();
$ciID = array();
I want to find matching values for all arrays using array_intersect
Arrays can be created and filled with values or not.
It can be only one populated array OR there can be all three. (later on there will be much more arrays.
How to iterate and create some kind of dynamic expression and get something like this:
array_intersect ($kaID, $tgID,$ciID,.... );
You can do something like this:
$collection = [];
//Dynamic
foreach($ids as $id) {
$collection[] = $id;
}
$result = call_user_func_array('array_intersect', $collection);
Related
I'm trying to create an unknown number of arrays dynamically inside a foreach loop, merge them all at the end into one array, and use this in a JSON format for Google Analytics.
So far I have the following code which is throwing an error at the merge part:
$p=1;
foreach(...){
...
$arr = 'arr'.$p;
$name = $order->ProductGroupName;
$name = str_replace("'", "", $name);
$arr = array(
"name"=>$name,
"id"=>$order->ProductCode,
"price"=>$order->RRP,
"quantity"=>$order->Quantity
);
$p++;
}
for ($q = 1; $q<$p; $q++){
$arry = 'arr'.$q;
$merge = array_merge($arry, $merge);
};
How do I create the arrays dynamically and merge them at the end, please?
I'm relatively new to PHP and have tried my best to get this to work.
I think I understand what you're trying to do. Just dynamically append [] to the array and you don't need to merge:
foreach($something as $order) {
$arr[] = array (
"name"=>str_replace("'", "", $order->ProductGroupName),
"id"=>$order->ProductCode,
"price"=>$order->RRP,
"quantity"=>$order->Quantity
);
}
If you want to have string keys for whatever reason, then:
$p = 1;
foreach($something as $order) {
$arr["SomeText$p"] = array (
"name"=>str_replace("'", "", $order->ProductGroupName),
"id"=>$order->ProductCode,
"price"=>$order->RRP,
"quantity"=>$order->Quantity
);
$p++;
}
And that's it. Check with:
print_r($arr);
Things like $arry = 'arr'.$q; stink of variable variables (though not done correctly) and shouldn't be used.
I need to tell array_merge_recursive what variables it needs to merge
I have the variable names that I need to use as strings, for example I have the following
$array1 = array('color'=>'blue', 'taste'=> 'sour', 'size'=>'big');
$array2 = array('color'=>'green', 'taste'=> 'sweet', 'size'=>'medium');
$array3 = array('color'=>'black', 'taste'=> 'sour', 'size'=>'small');
$array4 = array('color'=>'grey', 'taste'=> 'sweet', 'size'=>'big');
$allarrays = array_merge_recursive($array1, $array2, $array3, $array4);
This will work okay and merge my arrays, but I need to add a foreach to get the list of the arrays that I need and to set the array's that are going to the merged.
$arraysThatINeedToAddToTheMerge = array('array2', 'array4');
foreach ($arraysThatINeedToAddToTheMerge as $data){
$toBeMerged[] = $data;
}
$allarrays = array_merge_recursive($toBeMerged);
This doesn't work as it looks like I cannot use an array as the arguments for the array_merge_recursive.
I was thinking maybe I can use the list function for this but I haven't used it yet, what can I use to get what I need?
Two elements to handling this the way you want to:
Variable variables to build the to be merged array
$arraysThatINeedToAddToTheMerge = array('array2', 'array4');
$toBeMerged = [];
foreach ($arraysThatINeedToAddToTheMerge as $data){
$toBeMerged[] = $$data;
}
This will build an array of arrays, rather than simply an array of the names of your variables;
And (a modern PHP solution) then unpack the array arguments to be merged when calling array_merge_recursive
$allarrays = array_merge_recursive(...$toBeMerged);
or use call_user_func_array() for older versions of PHP
$allarrays = call_user_func_array('array_merge_recursive', $toBeMerged);
<?php
// get unordered array of Group objects
$groups = $this->getDoctrine()->getManager()->getRepository('AcmeDemoBundle:Group');
$array = array();
// map array to $groupName => $groupObject
foreach ($groups as $group) {
$array[$group->getName()] = $group;
}
Is there a shorter way to do that in PHP?
Note: Group names are unique, not empty strings.
I was thinking about array_walk, but I'm not sure if can replace the key somehow?
It seems there is no shorter/better way than the one posted in the question.
foreach ($topicarray as $key=>$value){
$files = mysql_query("mysqlquery");
while($file = mysql_fetch_array($files)){ extract($file);
$topicarray[$value] = array( array($id=>$title)
);
}
}
The first foreach loop is providing me with an array of unique values which forms a 1-dimensional array.
The while loop is intended to store another array of values inside the 1-dimensional array.
When the while loop returns to the beginning, it is overwriting it. So I only ever get the last returned set of values in the array.
My array ends up being a two dimensional array with only one value in each of the inner arrays.
Feels like I'm missing something very basic here - like a function or syntax which prevents the array from overwriting itself but instead, adds to the array.
Any ideas?
Step 1. Replace $topicarray[$value] with $topicarray[$value][]
Step 2. ???
Step 3. Profit
Make $topicarray[$value] an array of rows, instead of one row. Also, don't use extract here.
foreach ($topicarray as $key => $value) {
$rows = array();
$files = mysql_query("mysqlquery");
while($file = mysql_fetch_array($files)) {
$rows[] = array($file['id'] => $file['title']);
}
$topicarray[$value] = $rows;
}
Also, you should switch to PDO or MySQLi.
I have a PHP array that I'd like to duplicate but only copy elements from the array whose keys appear in another array.
Here are my arrays:
$data[123] = 'aaa';
$data[423] = 'bbb';
$data[543] = 'ccc';
$data[231] = 'ddd';
$data[642] = 'eee';
$data[643] = 'fff';
$data[712] = 'ggg';
$data[777] = 'hhh';
$keys_to_copy[] = '123';
$keys_to_copy[] = '231';
$keys_to_copy[] = '643';
$keys_to_copy[] = '712';
$keys_to_copy[] = '777';
$copied_data[123] = 'aaa';
$copied_data[231] = 'ddd';
$copied_data[643] = 'fff';
$copied_data[712] = 'ggg';
$copied_data[777] = 'hhh';
I could just loop through the data array like this:
foreach ($data as $key => $value) {
if ( in_array($key, $keys_to_copy)) {
$copied_data[$key] = $value;
}
}
But this will be happening inside a loop which is retrieving data from a MySQL result set. So it would be a loop nested within a MySQL data loop.
I normally try and avoid nested loops unless there's no way of using PHP's built-in array functions to get the result I'm looking for.
But I'm also weary of having a nested loop within a MySQL data loop, I don't want to keep MySQL hanging around.
I'm probably worrying about nested loop performance unnecessarily as I'll never be doing this for more than a couple of hundred rows of data and maybe 10 keys.
But I'd like to know if there's a way of doing this with built-in PHP functions.
I had a look at array_intesect_key() but that doesn't quite do it, because my $keys_to_copy array has my desired keys as array values rather than keys.
Anyone got any ideas?
Cheers, B
I worked it out - I almost had it above.I thought I'd post the answer anyway for completeness. Hope this helps someone out!
array_intersect_key($data, array_flip($keys_to_copy))
Use array_flip() to switch $keys_to_copy so it can be used within array_intersect_keys()
I'll run some tests to compare performance between the manual loop above, to this answer. I would expect the built-in functions to be faster but they might be pretty equal. I know arrays are heavily optimised so I'm sure it will be close.
EDIT:
I have run some benchmarks using PHP CLI to compare the foreach() code in my question with the code in my answer above. The results are quite astounding.
Here's the code I used to benchmark, which I think is valid:
<?php
ini_set('max_execution_time', 0);//NOT NEEDED FOR CLI
// BUILD RANDOM DATA ARRAY
$data = array();
while ( count($data) <= 200000) {
$data[rand(0, 500000)] = rand(0, 500000);
}
$keys_to_copy = array_rand($data, 100000);
// FOREACH
$timer_start = microtime(TRUE);
foreach ($data as $key => $value) {
if ( in_array($key, $keys_to_copy)) {
$copied_data[$key] = $value;
}
}
echo 'foreach: '.(microtime(TRUE) - $timer_start)."s\r\n";
// BUILT-IN ARRAY FUNCTIONS
$timer_start = microtime(TRUE);
$copied_data = array_intersect_key($data, array_flip($keys_to_copy));
echo 'built-in: '.(microtime(TRUE) - $timer_start)."s\r\n";
?>
And the results...
foreach: 662.217s
array_intersect_key: 0.099s
So it's much faster over loads of array elements to use the PHP array functions rather than foreach. I thought it would be faster but not by that much!
Why not load the entire result set into an array, then begin processing with nested loops?
$query_result = mysql_query($my_query) or die(mysql_error());
$query_rows = mysql_num_rows($query_result);
for ($i = 0; $i < $query_rows; $i++)
{
$row = mysql_fetch_assoc($query_result);
// 'key' is the name of the column containing the data key (123)
// 'value' is the name of the column containing the value (aaa)
$data[$row['key']] = $row['value'];
}
foreach ($data as $key => $value)
{
if ( in_array($key, $keys_to_copy))
{
$copied_data[$key] = $value;
}
}