Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do variable variables work in conjunction with ++ operator?

Tags:

variables

php

Given an array (ex: $a = [2,3,3,1,5,2]), find the first duplicate. In this case that would be the value 3, at index 2.

The second duplicate would be 2 because the index is higher(5).

A solution I found online:

function firstDuplicate($a) {
    foreach ($a as $v)
        if ($$v++) return $v;
        return -1;
}

How does $$v++ work?

$$v would be equal to $2 at first loop, $3 at second loop and so on.

How does ++ apply to this context? Thanks!

Later edit: When does $$v++ return true?

like image 700
Tiberiu Avatar asked May 09 '18 12:05

Tiberiu


2 Answers

There are two things at play here. The code is written in a quite interesting way, albeit complicated to understand.

First: variable variables

As you understood, yes on each interaction $$v will translate in variables, respectively $2, $3, $3, $1, $5, $2.

PHP is quite flexible (maybe even too much) so it allows* to test if ($2) even if $2 clearly was never instantiated before. It assumes NULL as its value, so the if check fails to pass.

* "Notice: Undefined variable: $2" will be thrown in the logs but that doesn't "break" the code nor prevents it's execution.

Second: Incrementing/Decrementing operators (++)

It's quite important to understand the difference between pre-increment and post-increment.

$a = 0;
$b = 0;

($a++ === 1) // FALSE
(++$b === 1) // TRUE

The pre-increment adds to the variable and then return it's (new, added) value; While the post-increment returns the variable's current value and only then adds to it.

Combining both

For readability, let's translate this one line

if ($$v++) return $v;

into

if ($$v) {
    return $v;
}
$$v = $$v + 1;

as that's what's really happening.


Jumping to the second iteration (the first 3 in the array, where $v = 3, we'd have:

// Right now $3 doesn't exist, so it's value is NULL
if ($3) { // "if (NULL)", so it's FALSE
    return 3;
}
$3 = $3 + 1; // "NULL + 1"
// $3 === 1 at this point

Why PHP compiles NULL + 1 = 1 that's another topic altogether ("too flexible", remember?). Bottomline it assumes NULL's numeric value is 0, so 0 + 1 = 1 is parsed.

Now when it comes to the third iteration (the second 3 in the array, where $v = 3 again - but at this time variable $3 exists and it's value is 1)

// Right now: $3 === 1
if ($3) { // TRUE
    return 3;
}
$3 = $3 + 1; // This line is never reached, the code has "returned" already

So that's it, hope it's somewhat easy to understand. It's a lot of different pieces that must be combined to make sense.

like image 199
mathielo Avatar answered Sep 25 '22 00:09

mathielo


$$ is part of "variable variables", a powerful but oh so often misused feature of PHP.

In your case, with $a = [2,3,3,1,5,2]

function firstDuplicate($a) {
    foreach ($a as $v)
        if ($$v++) return $v;
    return -1;
}

$$v will be equivalent to the variable $3 which is undefined.

Then $3++ will create a variable $3 with value 0 and the condition for the if statement will be false.

When $3++ is called again (when the duplicate is found) it will have value of 1, which makes the if statement pass and return $v; will terminate the function by returning the first duplicate (the value of $v).

Nota that: 0 is equal to False and every non-zero value is considered True.

like image 37
Radostin Stoyanov Avatar answered Sep 27 '22 00:09

Radostin Stoyanov