3

I have an array like this ...

[0,0,23,0,0,18,0,0]

Then I want to change values ​​that are not '0' (23 & 18) to auto increment, so the end result will be like this,

[0,0,1,0,0,2,0,0]

is there the best way for all that? So far this is what I did, but the results were not as expected ... :)

<?php

$arr = [0,0,23,0,0,18,0,0];
$x = 1;
$r = collect($arr)->map(function ($value, $key)use($x) {
    if ($value == 0) {
        return $value;
    } else {
        return $x++;
    }
})->all();

dd($r);
Don't Panic
  • 41,125
  • 10
  • 61
  • 80

2 Answers2

3

The problem is that when you have your value of $x passed into the function via use, this isn't allowing the value to be updated. You need to pass it by reference - use (&$x) to allow it to increment the value outside the function...

$r = collect($arr)->map(function ($value, $key) use (&$x) {
Nigel Ren
  • 56,122
  • 11
  • 43
  • 55
0

Another way... Using foreach with reference of array &

With Passed by Reference

Snippet

$arr = [0,0,23,0,0,18,0,0];
$counter = 1;
foreach ($arr as &$val){
   if($val !== 0){
      $val = $counter++;
   }
}
print_r($arr);

Note: Be aware of dangling reference


Without reference

Snippet

$arr = [0,0,23,0,0,18,0,0];
    $counter = 1;
    foreach ($arr as $key => $val){
       if($val !== 0){
          $arr[$key] = $counter++;
       }
    }
print_r($arr);

Output

Array
(
    [0] => 0
    [1] => 0
    [2] => 1
    [3] => 0
    [4] => 0
    [5] => 2
    [6] => 0
    [7] => 0
)

Live demo
Pass by reference docs

Shahnawaz Kadari
  • 1,423
  • 1
  • 12
  • 20