In regard to my question here, Jacob Relkin suggested a great solution of using call_user_func_array. That solved my problem but now I am really curious on how to do this in the absence of this function to achieve what I wanted in my original question which is below for reference:
Original Question:
I am creating an array of arrays in the following way:
$final_array = array();
for($i = 0; $i < count($elements); $i++) {
for($j = 0; $j < count($elements); $j++) {
if($i!=$j)
$final_array[] = array_intersect($elements[$i], $elements[$j]);
}
}
I am trying to find out the list of elements that occur in all the arrays inside the $final_array variable. So I was wondering how to pass this to array_intersect function. Can someone tell me how to construct args using $final_array[0], $final_array[1], ... $final_array[end_value] for array_intersect? Or if there is a better approach for this, that would be great too.
I am looking for a way to construct the following:
array_intersect($final_array[0], $final_array[1], $final_array[2], ...)
Well, the only real way to do this other than call_user_func_array would be to implode the resulting array into comma-separated arguments, then do something really really evil and use eval:
$args_imploded = implode(',', $some_array);
$result = eval('return array_intersect(' . $args_imploded . ')');
Why don't you just avoid the evil eval function and use the 'call_user_func_array' function? From what I understand about your code is that the $final_array parameter is an array of array's.
$result = call_user_func_array('array_intersect', $final_array);
No need for the eval function here.
EDIT: Stupid me. I didn't read your first paragraph properly ;). Please ignore this.
Related
Is there a built-in function or otherwise elegant way of prefilling an array with a repeating pattern of values.
Essentially what I require is a combination of the array_fill and str_repeat.
I am going to say No. I have never come across anything like this. I think the best thing to do would be your own for-loop that appends values to array in the pattern that you need.
How about this:
function array_pattern($input_array, $repeat_count) {
$output_array=array();
for($count = 1; $count < $repeat_count; $count++) {
$output_array = array_merge($output_array,$input_array));
}
return $output_array;
}
(will only work for keyed array, not associative arrays, but the whole repeating pattern thing doesn't really lend itself to assoc arrays anyway)
Please tell me which is the best way to unset middle element of associative array in PHP?
Suppose I have an array of 10,000 elements and I want to remove middle element of that array, which is efficient way to remove middle element?
$temp = array('name1'=>'value1','name2'=>'value2',...,'name10000'=>'value10000');
$middleElem = ceil(count($temp) / 2);
$i = 0;
foreach ($temp as $key=>$val) {
if ($i == $middleElem) {
unset($temp[$key]);
break;
}
$i++;
}
Is above code efficient way?
Considering $array is your array, this code remove the middle element if it has odd number of elements. If its event it'll remove the first of 2 middle elements.
$i = round(count($array)/2) - 1;
$keys = array_keys($array);
unset ($array[$keys[$i]]);
Test Result: http://ideone.com/wFEM2
The thing you have to figure out is what you want to do when you have an array with an even number of elements. What element do you want to get then?
The above code picks the 'lower' element, the code could easily be edited to make it pick the 'higher' element. The only thing you have to check is (what all others answers failed to do) what happens if you have three elements. It doesn;t pick the middle element, but the last. So you would have to add a check for that then.
$temp = Array("name1"=>"value1","name2"=>"value2",...,"name10000"=>"value10000");
$middleElem = ceil(count($temp)/2);
$keys = array_keys($temp);
$middleKey = $keys[$middleElem];
unset($temp[$middleKey]);
There ^_^
I think it's a proper way to do it. Try this:
array_remove_at( $temp, ceil(count($temp) / 2) - 1);
function array_remove_at(&$array, $index){
if (array_key_exists($index, $array)) {
array_splice($array, $index, 1);
}
}
You can find the size of the array, divide that number by two and then proceed to remove the element. Not sure about the performance isssues about that though
Firstly, I wouldn't worry too much about what is the most efficient way at this point. You're much better off coding for how easy the code is to read, debug and change. Micro-optimisations like this rarely produce great results (as they're often not the biggest bottlenecks).
Having said that, if you want a solution that is easy to read, then how about using array_splice.
$temp = array('name1'=>'value1','name2'=>'value2',...,'name10000'=>'value10000');
$middleElem = ceil(count($temp) / 2);
array_splice( $temp, $middleElem, 1 );
I would take it that the following code is more efficient, because you don't have to execute it in a loop. I generally follow the same pattern as Kolink, but my version checks if there actually is a "middle element". Works on all types of arrays, I think.
<?php
for( $i = 0; $i <= 9; $i ++ ) {
$temp['name'.$i] = 'value'.$i;
}
if( ( $count = count( $temp ) ) % 2 === 0 ) {
/** Only on uneven arrays. */
array_splice( $temp, ( ceil( $count ) / 2 ), 1 );
}
var_dump( $temp );
EDIT: Thavarith seems to be right; array_splice is much faster than simply unsetting the value. Plus, you get the added benefit of not having to use array_keys, as you already now at what $offset the middle is.
Proper way seems to be:
unset(arr[id]);
arr = array_values(arr);
For first removing element at index id and then re-indexing the array arr properly.
unset($myArray[key])
since your array is associative, you can drop any element easily this way
I am not sure if its a good idea, but i just thought it would be less tedious and much easier to declare variables on the fly using a for loop:
$val.$i = $row1[$i];. Now after trying this, this obviously isn't the right thing to do. Is there anyway i can improve this and not declare separate variables.
Maybe this will give a clearer picture:
for($i = 1; $i < 5; $i++) {
$val.$i = $row1[$i];
}
Now i want to achieve $val1 using $val.$i.
As others have posted, using an associative or 0-based array would be a far better implementation, but you can implement the solution just as you have requested using PHP's variable variable names:
for ($i = 1; $i <= 5; $i++)
{
${"val".$i} = "this is value " . $i;
}
echo "$val1<br />$val2<br />$val3<br />$val4<br />$val5";
Will output:
this is value 1
this is value 2
this is value 3
this is value 4
this is value 5
In PHP you can define variables by name.
Example:
$foo = 'bar';
$$foo = 'baz';
echo $bar; // echoes 'baz'
So in your case, it would look like:
$var = 'val'.$i;
$$var = $arr[$i];
Why you would do that, I have no idea.
A better system (imho) is to use list() construct:
list($val1, $val2, $val3) = $arr;
You could create an associative array and then use extract:
$arr = array();
// ...
$arr[$val.$i] = $row1[$i];
// ...
extract($arr);
Mind you, it will probably be better to use the array in the first place.
I believe you're trying to get all the data you are reading from your database into one easy to access place. All you need to do is shove each row into an array:
$allTheThings[] = $row1;
You'll end up with a two dimensional array where the first key is the row number and the second key is the column number.
I am not getting full picture of what you are trying to do, but to convert arrays into objects you would do this:
$val = (object) $row1;
im trying to create an array from a loop in PHP.
I want the array to end up something like $array(100,100,100,100), this is my code:
$x = 0;
while($x < 5){
$array[$x] = 100;
$x++;
}
echo $array[0];
It outputs 1 instead of 100.
Can someone tell me where i'm going wrong.
Even though it works perfectly for me, you should be initialising the variable beforehand.
$array = array();
For example, if $array is non-empty string, you will see the output of 1.
You can just use the predefined array_fill function for that:
$array = array_fill(0, 5, 100);
The other answers pretty much cover this. I would, however, recommend you use a for loop for this instead of a while loop if you're going to use a loop rather than a function to do it.
$array = array();
for($x=0; $x<5; $x++) {
$array[$x] = 100;
}
In fact, you could make this even shorter.
$array = array();
for($x=0; $x<5; $array[$x++]=100);
It's perfectly valid to have a for loop statement instead of a block. And blocks can go anywhere too; they don't need an if statement, for loop, while loop, or whatever, before them.
What's better to use in PHP for appending an array member,
$array[] = $value;
or
array_push($array, $value);
?
Though the manual says you're better off to avoid a function call, I've also read $array[] is much slower than array_push(). What are some clarifications or benchmarks?
I personally feel like $array[] is cleaner to look at, and honestly splitting hairs over milliseconds is pretty irrelevant unless you plan on appending hundreds of thousands of strings to your array.
I ran this code:
$t = microtime(true);
$array = array();
for($i = 0; $i < 10000; $i++) {
$array[] = $i;
}
print microtime(true) - $t;
print '<br>';
$t = microtime(true);
$array = array();
for($i = 0; $i < 10000; $i++) {
array_push($array, $i);
}
print microtime(true) - $t;
The first method using $array[] is almost 50% faster than the second one.
Some benchmark results:
Run 1
0.0054171085357666 // array_push
0.0028800964355469 // array[]
Run 2
0.0054559707641602 // array_push
0.002892017364502 // array[]
Run 3
0.0055501461029053 // array_push
0.0028610229492188 // array[]
This shouldn't be surprising, as the PHP manual notes this:
If you use array_push() to add one element to the array it's better to use $array[] = because in that way there is no overhead of calling a function.
The way it is phrased I wouldn't be surprised if array_push is more efficient when adding multiple values. Out of curiosity, I did some further testing, and even for a large amount of additions, individual $array[] calls are faster than one big array_push. Interesting.
The main use of array_push() is that you can push multiple values onto the end of the array.
It says in the documentation:
If you use array_push() to add one
element to the array it's better to
use $array[] = because in that way
there is no overhead of calling a
function.
From the PHP documentation for array_push:
Note: If you use array_push() to add one element to the array it's better to use $array[] = because in that way there is no overhead of calling a function.
Word on the street is that [] is faster because no overhead for the function call. Plus, no one really likes PHP's array functions...
"Is it...haystack, needle....or is it needle haystack...ah, f*** it...[] = "
One difference is that you can call array_push() with more than two parameters, i.e. you can push more than one element at a time to an array.
$myArray = array();
array_push($myArray, 1,2,3,4);
echo join(',', $myArray);
prints 1,2,3,4
A simple $myarray[] declaration will be quicker as you are just pushing an item onto the stack of items due to the lack of overhead that a function would bring.
Since "array_push" is a function and it called multiple times when it is inside the loop, it will allocate memory into the stack.
But when we are using $array[] = $value then we are just assigning a value to the array.
Second one is a function call so generally it should be slower than using core array-access features. But I think even one database query within your script will outweight 1000000 calls to array_push().
See here for a quick benchmark using 1000000 inserts: https://3v4l.org/sekeV
I just wan't to add : int array_push(...) returns
the new number of elements in the array (PHP documentation). which can be useful and more compact than $myArray[] = ...; $total = count($myArray);.
Also array_push(...) is meaningful when variable is used as a stack.