PHP:对于计数器的关联数组,在第一个增量之前显式地将每个值初始化为0是否更为惯用?

PHP:对于计数器的关联数组,在第一个增量之前显式地将每个值初始化为0是否更为惯用?,php,arrays,counter,Php,Arrays,Counter,我正在写一些代码来建立计数器的关联数组。当它第一次遇到一个新项时,它会创建一个新键并将其初始化为零。即: if (!array_key_exists($item, $counters)) { $counters[$item] = 0; } $counters[$item]++; 然而,PHP实际上隐式地完成了第一部分。如果我这么做 $counters[$item]++; 。。。然后,$counters[$item]将计算为NULL,并在递增之前转换为0。显然,第二种方法更简单、更简

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

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中,您只有第一个选项。

首选第一个选项。第二个选项将在日志中生成一个通知,$counters[$item]未定义。它仍然有效,但如果您更改display_errors=On;错误报告=全部。在php.ini文件中,您将在浏览器中看到这些注意事项。

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

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

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


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

但是,
array\u key\u exists
的用法不是很惯用。我知道,从Python开始,这似乎很自然,但如果您知道
$counter
没有有意义的
NULL
值,那么使用
isset()
测试数组成员资格更为惯用。(我看不出来,速度也快多了!)

下面是我用PHP编写计数器的方法:

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

不幸的是,与Python不同,PHP不提供任何不执行两个键查找的方法。

不管它是否惯用,出于您概述的原因,这是一个好主意。在PHP7中,您可以
$counters[$item]=($counters[$item]?0)+1注意:您还可以使用
错误报告(-1)在PHP代码中。把它放在脚本的顶部。我只是在第一次遇到它时初始化一个键,所以我不会得到任何未定义的/zero/NULL/任何键。啊,好吧,所以这和if(!isset($foo)){$foo=0;}大体上是一样的,我建议,总是初始化变量(如果可能的话,在这里:检查它们的存在性)-并且,检查它们的类型[即使PHP不是那种严格的类型]@djot它在后台执行一些额外的操作-保存当前的错误报告,将其设置为零,并在执行抑制块后恢复。啊,我想知道是否使用isset()这似乎更为PHP ISH,但来自其他语言,使用相同的函数来测试变量或数组密钥确实很奇怪。这是因为它很奇怪!!)PHP数组(它是一个哈希映射?一个列表?)也是非常奇怪的。
$counters = array();
foreach ($thingtobecounted as $item) {
    if (isset($counters[$item])) {
        $counters[$item]++;
    } else {
        $counters[$item] = 1;
    }
}