gerry_m
gerry_m

Reputation: 25

Conditionally add an extra element while pushing multi-element rows into a 2d array in a loop

I'm try to add an array element to an array (if a certain condition is met) before I push that row into a result array.

Right now, it adds the value as a separate, single-element row.

for ($i = 0; $i < 4; $i++) {
    $ret1[] = array("A" . $i, "B" . $i);
    if ($i > 2) {
        $ret1[] = array("C" . $i);
    }
}    
print_r($ret1);

Current result:

Array
(
    [0] => Array
        (
            [0] => A0
            [1] => B0
        )

    [1] => Array
        (
            [0] => A1
            [1] => B1
        )

    [2] => Array
        (
            [0] => A2
            [1] => B2
        )

    [3] => Array
        (
            [0] => A3
            [1] => B3
        )

    [4] => Array
        (
            [0] => C3
        )
)

Expected result:

(
    [0] => Array
        (
            [0] => A0
            [1] => B0
        )

    [1] => Array
        (
            [0] => A1
            [1] => B1
        )

    [2] => Array
        (
            [0] => A2
            [1] => B2
        )

    [3] => Array
        (
            [0] => A3
            [1] => B3
            [2] => C3
        )
)

Upvotes: 2

Views: 56

Answers (3)

mickmackusa
mickmackusa

Reputation: 48071

A modern approach is to unpack a conditionally populated temporary array as subarrays are pushed into the result array.

When an empty array is unpacked as it is appended to an array, no element will be added.

Code: (Demo)

$result = [];
for ($i = 0; $i < 4; ++$i) {
    $result[] = [
        "A$i",
        "B$i",
        ...$i > 2 ? ["C$i"] : []
    ];
}
var_export($result);

Upvotes: 0

Sherif
Sherif

Reputation: 11942

You can use a temporary variable to define the array. Then you can decide to push another element to it based on your condition. Finally you can push the temporary array to your $ret1 array to achieve the desired result.

for ($i=0; $i<5; $i++) {
    $arr = ["A$i", "B$i"];
    if ($i > 2) {
        $arr[] = "C$i";
    }
    $ret1[] = $arr;
}    

What you're doing is pushing 2 elements to the array in the last 2 iterations of your loop. One with a value of ["A3", "B3"] and another with a value of ["C3"] which just results in [["A3", "B3"], ["C3"]], which isn't what you're after. By using the temporary variable $arr we defer pushing the final array to $ret1 until after the conditional statement is executed or bypassed.

So for example, in the penultimate iteration of this loop the value of $arr is initially ["A3","B3"], then we push another value "C3" to the end of $arr based on $i > 2 being true, which makes $arr = ["A3","B3","C3"], and finally we push $arr to the end of the array $ret1 giving us the final result [ ..., 3 => ["A3","B3","C3"], ...]

Bonus notes

None of this is critical to your problem or your question, but I figured I'd throw it out there just in case.

In PHP, double quoted strings give you automatic variable expansion. Which means that "A$i" === "A" . $i. So just something to consider. Additionally, there is a short-hand syntax for arrays, which has been available since PHP 5.4.0 and in my personal opinion is easier to write and read than using the traditional array() construct. So array("A" . $i, "B" . $i) === ["A$i", "B$i"].

Upvotes: 1

Don&#39;t Panic
Don&#39;t Panic

Reputation: 41820

What you're doing is not giving you the results you expect because each time you use

$ret1[] = something

PHP automatically creates a new index in $ret.

If you want to append another string to the array you have just inserted into $ret you can specify the current key with $ret1[$i][] = "C" . $i; instead of $ret1[] = array("C" . $i);.

Upvotes: 1

Related Questions