2

我正在编写一些代码来构建计数器的关联数组。当它第一次遇到新项目时,它会创建一个新密钥并将其初始化为零。IE:

if (!array_key_exists($item, $counters)) {
    $counters[$item] = 0;
}
$counters[$item]++;

然而,PHP 实际上隐含地完成了第一部分。如果我只是...

 $counters[$item]++;

...然后 $counters[$item] 将评估为 NULL 并在递增之前转换为 0。显然第二种方式更简单,更简洁,但感觉有点低俗,因为 $counters[$item] 可能还不存在并不明显。在 PHP 中是首选的一种方式还是另一种方式?

相比之下,在 Python 中,惯用的方法是在您想要将自己初始化为 0 的键时使用 collections.Counter,当您想要自己初始化它们时使用常规字典。在 PHP 中,您只有第一个选项。

4

4 回答 4

4

增加一个未初始化的键会产生一个 PHP 通知,这是一个坏主意。您应该始终先初始化。

但是,使用的array_key_exists不是很地道。我知道来自 Python 可能看起来很自然,但是如果您知道它$counter没有有意义的值,那么使用它来测试数组成员资格会NULL更惯用。isset()(它也快得多,我无法辨别!)

这就是我在 PHP 中编写计数器的方式:

$counters = array();
foreach ($thingtobecounted as $item) {
    if (isset($counters[$item])) {
        $counters[$item]++;
    } else {
        $counters[$item] = 1;
    }
}

不幸的是,与 Python 不同,PHP 不提供任何方法来执行此操作而无需执行两个键查找。

于 2013-04-05T21:04:58.077 回答
3

第一个是首选。第二个选项将在您的日志中生成一条通知,说明 $counters[$item] 未定义。它仍然有效,但如果您更改 display_errors = On; 和error_reporting = E_ALL。在您的 php.ini 文件中,您将在浏览器中看到这些通知。

于 2013-04-05T20:49:08.987 回答
2

第一种方法通常是你如何做,如果只是为了更简单的维护。请记住,您可能不是维护代码的人。您不希望错误日志中充斥着正确操作的代码。更糟糕的是,您可能需要将方法转移到可能不会发生隐式初始化的其他语言(或早期版本的 PHP)。

于 2013-04-05T20:54:10.067 回答
-1

如果您真的不需要检查每个数组索引 - 或者知道大多数索引将是未定义的 - 为什么不抑制以下错误:?

(这样可以节省一些初始化 [无用] 索引的性能)

if (@!array_key_exists($item, $counters)) {
于 2013-04-05T20:58:07.637 回答