Multiply each integer in a flat array by 60
Asked Answered
I

5

19

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.

Indebtedness answered 17/4, 2010 at 21:30 Comment(3)
I would go for the array_map / bcmul solution Gordon provided if you don't want to use foreach or custom functions yet, have you considered not multiplying the array by 60 and instead divide the PHP time by 60?Dropforge
I am going to try all of the examples, just so I know how to do it in future. The foreach loop seems to be the most simple. What is the difference between *= and *?Indebtedness
Henryz: $a *= 6 is the short form of $a = $a * 6Typhoid
G
11

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

foreach ($times as $value) {

  $new_times[] = $value * 60;

}
Gallegos answered 17/4, 2010 at 21:34 Comment(0)
D
29

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.

Degenerate answered 17/4, 2010 at 21:34 Comment(1)
There is wrong that array_map returns the modified array, in your examples you must do an $input = array_map... otherwise it doesn't modifiy $input. There is array_walk for that.Wyrick
G
11

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

foreach ($times as $value) {

  $new_times[] = $value * 60;

}
Gallegos answered 17/4, 2010 at 21:34 Comment(0)
T
6

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.

Typhoid answered 17/4, 2010 at 21:34 Comment(1)
doesn't work in PHP 7.2.6 anymore: " An iterator cannot be used with foreach by reference "Bonzer
A
3

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.

Alkmaar answered 17/4, 2010 at 23:28 Comment(2)
Hi, thanks for the answer, this only seemed to work if it built a new array like this v=[]. Not sure why :SIndebtedness
Because you must assign the returned value by array_map to a variable to hold the modified values. You can reuse the same $input_array if you want as $input_array = array_map....Wyrick
S
3
array_walk($myArray, function(&$v) {$v *= 60;});
Schwarzwald answered 17/3, 2016 at 12:39 Comment(1)
While this code snippet may solve the question, including an explanation really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. - From reviewKitchenmaid

© 2022 - 2024 — McMap. All rights reserved.