0

The following is the best way to iterate through and modify array in PHP5.*+

(source: http://zend-php.appspot.com/questions_list -- question #3)

$array = array("one" => 1, "two" => 2, "three" => 3, "four" => 4, "five" => 5);
foreach($array as $key => &$val) {
   $val += 1;
}

What is it about this method of iterating and modifying that makes it better than others?

Can someone please explain how come this actually works?

This iterates just fine, why include as $key => &$val if we are not using the keys?, also why do we need to include the & in &$val:

foreach($array as $val){
   echo $val;
}

I appreciate the explanation, Thanks in advance!

AnchovyLegend
  • 12,139
  • 38
  • 147
  • 231

2 Answers2

2

Since they intend to modify the value, getting it as a reference is clever.

$array = array("one" => 1, "two" => 2, "three" => 3, "four" => 4, "five" => 5);
foreach($array as $key => &$val) {
   $val += 1;
}

Will add 1 to all values.

If you did:

foreach($array as $key => $val) {
   $val += 1;
}

Nothing would happen.

I strongly disagree that it is the best way though. I much prefer to see:

foreach($array as $key => $val) {
   $array[$key] += 1;
}

because it's much more straightforward. I'll gladly believe it doesn't perform as well, but I also don't care (unless there is a reason to start optimizing).

It's also worth mentioning that using references can lead to strange situations, such as: PHP reference causes data corruption

PS. I didn't downvote. I'm getting really annoyed by people downvoting and not leaving a comment.

Community
  • 1
  • 1
Halcyon
  • 57,230
  • 10
  • 89
  • 128
  • In some programming languages - C# and Java (I think) you can not modify the elements that you get using foreach. From this answer it seems that in PHP you could do that, so maybe that's the reason behind `$key => $val`. – Leron Oct 31 '13 at 17:12
  • `foreach($array as $key => $val) { $val += 1; } ` **does** modify the values! Please edit! – AnchovyLegend Oct 31 '13 at 17:13
  • Just tested it, using your '**proof**'. It modifies `$val` values within the scope of the `foreach` loop, so something **does** happen. Obviously the values are lost outside of the loop, if that's what you mean by 'nothing happens'. – AnchovyLegend Oct 31 '13 at 17:15
  • I'd say that `$array[$key] += 1` is more error prone when you're renaming the `$array` variable. Reducing the redundancy and thereby coupling of code by using a reference is ever so slightly more reliable in this scenario and hence preferably, IMHO. It also expresses the intention better, IMHO. – deceze Oct 31 '13 at 17:16
  • Maybe the OP misses the `&` in `foreach($array as $key => &$val)` which i think makes it possible to manipulate the data. Is that right? – Leron Oct 31 '13 at 17:18
  • 1
    deceze there is no such concern if you use variable renaming / refactoring macros that all modern IDEs have. - @Leron, yes, it causes the value to be passed as a reference. AnchovyLegend, yes that is what I meant, the changes don't persist outside of the loop. – Halcyon Oct 31 '13 at 17:19
  • Well, in this case I think that `foreach` should be used only to display data. Even though passing by reference do the trick it seems a little bit like a hack to me and also, I think there's a good reason `foreach` to be implemented like this. So maybe that's part of the answer - `foreach` is optimized for displaying data and no manipulating (though I'm not sure that's the case). – Leron Oct 31 '13 at 17:23
  • Isn't this more optimal, since we are not using the keys anyways? `foreach($array as &$val) { $val += 1; }` **note:** it modifies that actual array value outside the scope of the array. – AnchovyLegend Oct 31 '13 at 17:30
  • 1
    Sure, if you don't need the key in your loop this is probably even better. This does show you how trivial Zend certification is though. I don't believe there is a single best solution because what the best solution is may change over time. I'd rather ask about the reasoning, which is a much more valuable skill to have. – Halcyon Oct 31 '13 at 17:34
1

The question is as follows:

What is the best way to iterate and modify every element of an array using PHP 5?

These are the four choices listed in the link:

// method one
for($i = 0; $i < count($array); $i++) { 
    /* ... */ 
}

// method two
foreach($array as $key => &$val) { 
    /* ... */ 
}

// method three
foreach($array as $key => $val) { 
    /*... */ 
}

// method four
while(list($key, $val) = each($array)) { 
    /* ... */ 
}

The options 1, 3 and 4 are okay and they will work for iterating through the array. However, to modify the original array, you'll need to pass the $val by reference, which is what the second option does. That's why it's the preferred solution, in this case.

Amal Murali
  • 75,622
  • 18
  • 128
  • 150