php 如何正确地递增某个数组键,即使需要创建键?

xfb7svmp  于 2023-02-28  发布在  PHP
关注(0)|答案(4)|浏览(205)

假设您需要创建某种类型的"top",并具有如下代码:

$matches=array();
foreach ($array as $v){
   $matches[processing($v)]++;  
}

对于需要创建索引的情况,这将输出**Notice: Undefined index**。
既然您知道必须创建索引,那么处理这些情况的最佳方法是什么?
我根据具体情况使用了以下解决方案:
1.抑制错误@$matches[$v]++;

    • 亲**:非常容易打字
    • 缺点**:缓慢

1.检查是否设置为$matches[$v]=isset($matches[$v])?$matches[$v]++:1;

    • 专业**:更快
    • 缺点**:即使以速记形式书写也需要更长时间,需要再使用$matches [$v] 2次

还有别的办法吗?
寻找最快的执行时间,因为我使用这个函数数千次,或者寻找更懒的方式键入,但仍然比@快

    • 编辑:**

在一个简单的例子中,您有$matches[$v]++;,您也可以使用array_count_values()(如Yoshi建议的)

rqqzpn5f

rqqzpn5f1#

经过一些阅读,写作和测试我得到了一些东西:

function inc(&$var){
    if (isset($var)) $var++;else $var=1;
}

以为我找到了金子但先看看测试结果。

测试代码:

$a=array();

// Pre-Fill array code goes here
for($i=1;$i<100000;$i++) {
    $r=rand(1,30000);
    //increment code goes here
}

// Remove extra keys from array with:
//foreach ($a as $k=>$v) if ($v==0) unset($a[$k]);

执行时间:* (仅供参考)*

inc($a[$r])                             1.15-1.24
@$a[$r]++                                   1.03-1.09
$a[$r]=array_key_exists($r,$a)?$a[$r]++:1;  0.99-1.04

$a[$r]=!empty($a[$r])?$a[$r]++:1;               0.61-0.74
if (!empty($a[$r])) $a[$r]++;else $a[$r]=1; 0.59-0.67
$a[$r]=isset($a[$r])?$a[$r]++:1;                0.57-0.65
if (isset($a[$r])) $a[$r]++;else $a[$r]=1;  0.56-0.64

//with pre-fill
$a=array_fill(0,30000,0);                   +0.07(avg)
for($i=1;$i<=30000;$a[$i++]=0);             -0.04(avg)

//with pre-fill and unset
$a=array_fill(0,45000,0);                   +0.16(avg)
for($i=1;$i<=45000;$a[$i++]=0);             +0.02(avg)

结论:

  • @当然是输入速度最快的,我看不出使用它有什么问题在这种情况下,但也可以随时检查这个问题:Suppress error with @ operator in PHP
  • 通过ini_set()完全抑制错误(在循环之前和在循环之后使能错误)在性能上比所有的都差
  • inc()看起来很好很干净,易于输入,并且执行检查而不是抑制,但是调用它看起来比@还要慢
  • isset()empty()稍快,但两者的性能基本相同
  • 有趣的是,使用shorthandif语句会稍微慢一些
  • 预填充数组时获得的最佳结果。即使长度未知,在大型数据集上进行良好的预测仍然会稍微快一些
  • 奇怪的是,array_fill()for花费的时间略长!

RFC

我不认为这个答案是100%完整的,尽管现在看起来isset()是最快的,@是最懒的。
任何意见和想法都是赞赏!

nr9pn0ug

nr9pn0ug2#

您也许可以初始化matches数组,使用array_combine$array中的值组合为键,使用array_fill将值填充为初始值0

$matches = array_combine(array_values($array), array_fill(0, count($array), 0));
sr4lhrrt

sr4lhrrt3#

我总是这样做:

$matches=array();

foreach ($matches as $v){

    /* if $v is not empty, add 1, otherwise $v= 1 */
    $matches[$v]=(!(empty($matches[$v]))) ? $matches[$v]++ : 1;
}

你说得对。这是有点罗嗦,但公平地说,它是相当简洁的同时。我用empty()而不是isset()虽然。不知道这是快或慢了我的头顶部。我认为它可能是慢。

    • 编辑**

为了回答你的编辑,我会这样做:

$matches=array();

foreach ($matches as $v){

    $x=function($v);

    /* if $v is not empty, add 1, otherwise $v= 1 */
    $matches[$x]=(!(empty($matches[$x]))) ? $matches[$x]++ : 1;
}

这样,您只需调用该函数一次。

6za6bjd0

6za6bjd04#

PHP 7+解决方案:

$arr[$key] = ($arr[$key] ?? 0) + 1;

相关问题