tags:

views:

139

answers:

4

I have an array called $times. It is a list of small numbers (15,14,11,9,3,2). These will be user submitted and are supposed to be minutes. As PHP time works on seconds, I would like to multiply each element of my array by 60.

I've been playing around with array_walk and array_map but I can't get those working :S

Thanks.

+1  A: 

Just iterate over the array with the foreach statement and multiply:

foreach ($times as $value) {

  $new_times[] = $value * 60;

}
DKinzer
This worked very well for what I was trying to do, thanks.
Henryz
+9  A: 

You can use array_map:

array_map() returns an array containing all the elements of arr1 after applying the callback function to each one. The number of parameters that the callback function accepts should match the number of arrays passed to the array_map()

Examples with lambda functions for callbacks:

array_map(function($el) { return $el * 60; }, $input);

Same for PHP < 5.3

array_map(create_function('$el', 'return $el * 60;'), $input);

Or with bcmul for callback

array_map('bcmul', $input, array_fill(0, count($input), 60));

But there is nothing wrong with just using foreach for this as well.

Gordon
Array map is silly to use for such a simple task. It's supposed to be used for mapping the values to callback functions that probably do a lot more than just multiply by 60.
DKinzer
@DKinzer there is nothing in the PHP manual that justifies your claim. In fact, the examples given are pretty similar to the UseCase asked for. You might argue they are simple so they are easy to understand, but then we have to agree to disagree.
Gordon
The last example is at least factor 10 faster for me. Anyways, i'm fine with both. Loops are currently just more straight forward in php.
elias
I believe foreach() has better performance. You save the overhead from the function's call at each iteration.
Savageman
Odd. I did another profiling. This time with Zend Debugger instead of PEAR benchmark and it yields totally different results that indeed suggest foreach is 5.5x faster. In fact, I was surprised that it shouldn't be myself, but can benchmarks lie? Apparently, so I removed the statistic. But still, even with foreach being much faster, we're still talking about 0.0000xx seconds per run. Don't even get me started on function call overhead. Yes, it exists, but it's so tiny that it's not worth mentioning it.
Gordon
I am with Gordon. If you ever have to worry about these sort of performance considerations, you are using the wrong language.
Yacoby
+3  A: 

You may want to use foreach for simplicity in your case:

foreach( $times as &$val ){ $val *= 60; }

I assume that the values of your array are the ones you want to multiply, not the keys. As the above solution uses references, it will also alter your original array - but as you were aiming at array_map before, I think that you want that.

The solution above is probably easier to understand and most likely faster than using array_map which (obviously) has to call a function for each element. I'd use array_map only for more complicated things such as advanced sorting algorithms and so on, but definitely not for something as trivial as this.

lamas
A: 

I'd personally second the suggestion from Gordon to just use a lambda (or created) function and either do:

array_map(function($el) { return $el * 60; }, $input_array);

(PHP >= 5.3) or

array_map(create_function('$el', 'return $el * 60;'), $input_array);

(PHP < 5.3)

Definitely I see no reasons for duplicating the array (can become cumbersome if lot of values are involved); also, pay attention that using foreach (which I second can be handy) can also be dangerous if you're not working with it carefully ...and then maintenance can become daunting anyways (because you have to remember to deal with it every time you work on that code). If you have no reasons for optimizing at this stage (IE your application has not problems of speed), don't do it now and don't worry about using array_map. You can think about ease of maintenance now and optimize later, in case you really need to.

In fact, if you go by reference and then you use foreach again, you might step into unexpected results (see example below...)

$a=array('1','2','3');

foreach ($a as &$v) {
        $v *= 60;
}
print_r($a);
foreach ($a as $v);
print_r($a);

Output is:

Array ( [0] => 60 [1] => 120 [2] => 180 )

Array ( [0] => 60 [1] => 120 [2] => 120 )

Probably not what you expect on the second cycle. This is why I usually avoid the foreach & byref combo when I can.

maraspin
Hi, thanks for the answer, this only seemed to work if it built a new array like this v=[]. Not sure why :S
Henryz