0

I'm looking for the equivalent in PHP of the following Python code:

d = {a*2:a*3 for a in range(5)}

Here's an ugly one-line solution:

$d = array_combine(array_map(function ($x) {return $x*2;}, range(0,4)), array_map(function ($x) {return $x*3;}, range(0,4)));

And here's a more readable solution that uses a loop :(

$d = [];
foreach(range(0,4) as $x) {
    $d[$x*2]  = $x*3;
}

Is there a simpler and better way to do this in PHP?

Peretz
  • 5
  • 2
  • This may help: http://stackoverflow.com/questions/1266911/does-php-have-an-equivalent-to-pythons-list-comprehension-syntax – Architect Nate Feb 04 '16 at 21:32
  • `foreach` is the simplest solution in your case – RomanPerekhrest Feb 04 '16 at 21:33
  • python code uses loop too.."that uses a loop :(".. `for a in range(5)` it's a loop.. – ern Feb 04 '16 at 21:44
  • @ern You're right -- I think I was thinking of something else -- e.g. the way it's better (i.e. takes less resources) to use join in python instead of concatenating a string in a for loop. I also had the impression that list/dict comprehensions were computationally preferable. But I have no idea how it works with an array in php, so maybe it's just as efficient with a loop instead of something like array_map. – Peretz Feb 05 '16 at 21:49

1 Answers1

3

There is no dictionary comprehension syntax in PHP. When looking for the shortest and/or most efficient code to produce the same output, I would propose this:

1. range(from, to, step)

You can make use of the third parameter of the range function:

$d = array_combine (range(0,8,2), range(0,12,3));

Output of var_export($d):

array (
  0 => 0,
  2 => 3,
  4 => 6,
  6 => 9,
  8 => 12,
)

Of course, this only works if your expressions are linear.

2. foreach

The foreach loop really is the cleanest and most readable way to handle this. Note that you have a little error in your version: the range function needs at least 2 arguments.

Also, PHP does not require you to initialise $d as it will do so upon the first assignment in the loop. Finally, you don't need the braces, although your preferred coding style may require the use of them:

foreach (range(0,4) as $x) $d[$x*2] = $x*3;

In number of characters this line is even shorter than the first solution.

trincot
  • 317,000
  • 35
  • 244
  • 286
  • That's nice.. Actually there is no equivalent of dictionary comprehensions or list comprehension in php .. http://keeponcoding.com/python-list-and-dict-comprehensions-for-php-developers.html .. Still this is one of the bests he can do.. – ern Feb 04 '16 at 22:37
  • 1
    Thanks, @ern, you are of course are right: PHP has no equivalent. I added this fact at the top of my answer, and added 2 alternatives. – trincot Feb 05 '16 at 09:40
  • Thanks! The first solution is smart but doesn't help because I changed the functions, etc. to make the problem simpler to state outside of the context of my application. The second looks great -- I wanted a readable one-liner. @ern Thanks for that link, it's helpful. – Peretz Feb 05 '16 at 21:44