Как переменные переменные работают в сочетании с оператором ++? - PullRequest
0 голосов
/ 09 мая 2018

Учитывая массив (например: $a = [2,3,3,1,5,2]), найдите первый дубликат. В этом случае это будет значение 3 с индексом 2.

Вторым дубликатом будет 2, потому что индекс выше (5).

Решение, которое я нашел онлайн:

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

Как работает $$v++?

$$v будет равно $ 2 в первом цикле, $ 3 во втором цикле и так далее.

Как ++ относится к этому контексту? Спасибо!

Позднее редактирование: когда $$ v ++ возвращает true?

Ответы [ 2 ]

0 голосов
/ 09 мая 2018

Здесь есть две вещи. Код написан довольно интересным способом, хотя и сложным для понимания.

Первый: переменные

Как вы поняли, да при каждом взаимодействии $$v будет переводить в переменные соответственно $2, $3, $3, $1, $5, $2.

PHP довольно гибок (возможно, даже слишком много ), поэтому позволяет * проверять if ($2), даже если $2 явно никогда не создавался ранее. Он принимает NULL в качестве значения, поэтому проверка if не проходит.

* «Примечание: неопределенная переменная: $ 2» будет добавлена ​​в журналы, но это не «нарушает» код и не препятствует его выполнению.

Второй: Операторы увеличения / уменьшения (++)

Очень важно понимать разницу между преинкрементом и постинкрементом.

$a = 0;
$b = 0;

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

Предварительное увеличение добавляет к переменной и затем возвращает ее (новое, добавленное) значение; Тогда как постинкремент возвращает текущее значение переменной и только потом добавляет к нему.

Объединение обоих

Для удобства чтения давайте переведем эту строку

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

в

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

поскольку это то, что действительно происходит.


Переход к второй итерации (первая 3 в массиве, где $v = 3, мы бы получили:

// 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

Почему PHP компилирует NULL + 1 = 1 Это совсем другая тема («слишком гибкая», помните?). В итоге предполагается, что NULL числовое значение равно 0, поэтому 0 + 1 = 1 анализируется.

Теперь, когда дело доходит до третьей итерации (вторая 3 в массиве, где $v = 3 снова - , но в это время переменная $3 существует, и ее значение равно 1)

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

Вот и все, надеюсь, это несколько легко понять. Это много разных частей, которые должны быть объединены, чтобы иметь смысл.

0 голосов
/ 09 мая 2018

$$ является частью "переменных переменных", мощной, но очень часто неправильно используемой функции PHP.

В вашем случае с $a = [2,3,3,1,5,2]

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

$$v будет эквивалентно переменной $3, которая не определена.

Затем $3++ создаст переменную $3 со значением 0, и условие для оператора if будет ложным.

Когда $3++ вызывается снова (когда обнаружен дубликат), он будет иметь значение 1, что делает оператор if проходным, а return $v; завершит функцию, возвращая первый дубликат (значение $v).

Примечание: 0 равно False, и каждое ненулевое значение считается True.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...