给定一个数组(例如:$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?
答案 0 :(得分:8)
这里有两件事情可做。代码以一种非常有趣的方式编写,虽然很难理解。
根据您的理解,每次互动时都会{是} $$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
就是这样,希望它有点容易理解。这是必须结合才能有意义的许多不同部分。
答案 1 :(得分:3)
$$
是“变量变量”的一部分,这是一个功能强大但经常被滥用的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语句的条件将为false。
再次调用$3++
时(找到重复项时),其值为1
,这会使if
语句通过,return $v;
将终止该函数通过返回第一个副本($v
的值)。
注意:0
等于False
,每个非零值都被视为True
。