在PHP中尝试增加关联数组时出现"Notice: Undefined index"的错误

5
我试图每次出现重复变量时增加$variable的值。我不确定这是否在语法上正确,但我认为在语义上是正确的。var_dump似乎输出了正确的结果,但我收到了以下错误提示:注意:未定义索引...
$newarray = array();
foreach ($array as $variable)
{
    $newarray[$variable]++; 
    var_dump($newarray);
}
$array = (0 => h, 1 => e, 2 => l, 3 => l, 4 => o);
目标:将以上代码中的数组赋值转换成可读性更强的格式。
'h' => int 1
'e' => int 1
'l' => int 2
'o' => int 1

我的代码是正常工作的,只不过我得到了一些奇怪的注意。


这不是一个好的实践,而且我真的不知道这个操作有多少优化,但你可以在操作前面添加@,像这样@$newarray[$variable]++;这样通知就会被抑制。坏处是,如果你真的有问题,它将不会被显示 :) - Catalin
问题已通过添加isset检查得到解决。 - diesel
7个回答

10
$newarray = array();
foreach ($array as $variable)
{
    if (!isset($newarray[$variable])) {
        $newarray[$variable] = 0;
    }
    $newarray[$variable]++;
}

1
谢谢!那个isset解决了问题。但我仍在努力弄清楚为什么需要那个检查? - diesel
如果数组中不存在该键,则将其添加并设置为0,这就是原因。明白了。 - diesel
4
难道不应该改为 "$newarray[$variable] = 1;" 吗?否则,第一个“增量”将被设置为零(因此不会被计算在内!) - barryhunter
请注意,答案已经被编辑为正确的形式。它将把值设置为0,然后立即递增它,因此实际上不会输出0。 - Miral

3
在现代的PHP中,你可以通过利用空合并运算符来避免使用isset()函数。在下面的代码片段中,这种技术会将变量设置为0,如果该变量尚未声明。然后,你可以自由地使用一系列简写操作,如字符串连接、算术运算等。
$new = [];
foreach ($array as $v) {
    $new[$v] = ($new[$v] ?? 0) + 1;
}

或者,如果你想继续使用++,那么你可以使用"null合并赋值运算符"。如果变量已经声明,赋值运算符右侧的逻辑甚至不会被执行。下面的代码片段将与上面的代码片段完全相同。
$new = [];
foreach ($array as $v) {
    $new[$v] ??= 0;
    ++$new[$v];
}

关于您的样本数据和所需的字母和计数结果,我可能会使用完全本地化、功能性的方法。(演示
var_export(
    array_count_values(str_split('hello'))
); // letters are in the same order as they were encountered

同样的结果,远不如此技术吸引人。
$assoc = count_chars('hello', 1);
var_export(
    array_reduce(
        array_keys($assoc),
        fn($result, $k) => $result += [chr($k) => $assoc[$k]],
        []
    )
); // letters are alphabetized

我希望这可以在一行上完成,而不需要在该行中重复变量本身。当将统计数据或数字收集到较大的数组中时,变量声明可能会变得冗长。 - Sandman
目前,PHP没有“null coalescing addition assignment”运算符。这个神话般的生物可能看起来像这样:??+=或者“null coalescing incrementation ??++”。但是,PHP将走上一条不太人类可读的符号序列之路。 - mickmackusa

3
请看函数array_count_values()。它正好可以实现您所需的功能。
来自php.net的示例:
$array = array(1, "hello", 1, "world", "hello");
print_r(array_count_values($array));

结果:

Array
(
    [1] => 2
    [hello] => 2
    [world] => 1
)

1
<?php
$newarray = array();
foreach ($array as $variable) {
    if ( !array_key_exists($variable, $newarray) ) {
        $newarray[$variable] = 0;
    }
    ++$newarray[$variable];
}
var_dump($newarray);

但你也可以使用array_count_values()


0
$newarray = array();
foreach ($array as $variable)
{
    if(!isset($newarray[$variable]))
      $newarray[$variable] = 0;

      $newarray[$variable]++; 
    var_dump($newarray);
}

谢谢,我已经解决了这个问题。我漏掉了isset检查。 - diesel

0
我真的很喜欢mickmackusa在代码中使用null合并运算符。
$new = [];
foreach ($array as $v) {
    $new[$v] ??= 0;
    ++$new[$v];
}

但是你可以使用数组元素引用来节省第二次查找,如果不存在,它会自动插入一个null元素。
$new = [];
foreach ($array as $v) {
    $entry =& $new[$v];
    ++$entry;
}

幸运的是,递增运算符将null视为零,并按预期递增为1。

-2

你正在增加错误的东西,请尝试使用这个:

foreach ($array as $key => $variable) {
   $array[$key]++; 
   var_dump($array);
}

糟糕,我觉得之前的代码有点不清楚,我已经更新了它。不确定那是否仍然是问题所在。 - diesel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接