【问题标题】:increment value inside an array of arrays (if key is non-existent, set it to 1)在数组数组中增加值(如果键不存在,则将其设置为 1)
【发布时间】:2014-12-10 05:37:13
【问题描述】:

问题已更新以澄清

对于简单的数组,我发现使用$arr[$key]++ 填充新元素或增加现有元素很方便。例如,计算水果的数量,$arr['apple']++ 将在第一次遇到“apple”时创建数组元素$arr('apple'=>1)。随后的迭代只会增加“apple”的值。无需添加代码来检查键“apple”是否已存在。

我正在填充一个数组数组,并希望在嵌套数组的元素中实现与上述示例类似的“单线”。

$stats 是数组。 $stats 中的每个元素都是另一个具有 2 个键(“name”和“count”)的数组

我希望能够将数组推入$stats - 如果键已经存在,只需增加“计数”值。如果它不存在,则创建一个新的元素数组并将计数设置为 1。并在一行中执行此操作,就像上面的简单数组示例一样。

在代码中,这看起来像(但不起作用):

$stats[$key] = array('name'=>$name,'count'=>++);
or 
$stats[$key] = array('name'=>$name,++);

寻找有关如何在无需检查元素是否已存在的情况下实现此目的的想法。

背景:

我在一组对象中循环,查看每个对象中的“数据”元素。这是数组中的一个片段:

[1] => stdClass Object
    (
        [to] => stdClass Object
            (
                [data] => Array
                    (
                        [0] => stdClass Object
                            (
                                [name] => foobar
                                [id] => 1234
                            )

                    )

            )

我想计算“id”的出现次数并将其与“name”相关联。 (“id”和“name”是唯一的组合 - 例如,name="foobar" 将始终具有 id=1234)

id     name   count
1234  foobar    55
6789  raboof    99

我目前正在使用数组数组$stats 来捕获信息(我对其他实现持开放态度。我查看了array_unique 但我的原始数据在数组和对象的深处) .

第一次遇到“id”(例如1234),我会在$stats创建一个新数组,并将计数设置为1。对于后续命中(例如:id=1234),我只想增加count

对于一维数组,$arr[$obj->id]++ 工作正常,但我不知道如何为数组数组推送/递增。对于多维数组,如何在一行中推送/递增?

提前致谢。

$stats = array();
foreach ($dataArray as $element) {
  $obj = $element->to->data[0];
  // this next line does not meet my needs, it's just to demonstrate the structure of the array
  $stats[$obj->id] = array('name'=>$obj->name,'count'=>1);

  // this next line obviously does not work, it's what I need to get working
  $stats[$obj->id] = array('name'=>$obj->name,'count'=>++);
}

【问题讨论】:

  • 如果数组中不存在 $key,您确定 $array[$key]++ 可以正常工作吗?我还没有找到使用 isset() if 条件的方法。这种丑陋真的让我很恼火,因为我来自 perl 背景,您可以 ++ 或几乎对不存在的数组索引执行任何其他操作并动态创建它。
  • @ChrisNadovich 是的,我经常使用它。 php 5+ 和 7+
  • 它会引发警告。你至少需要用@ 压制它,这更讨厌

标签: php arrays


【解决方案1】:

尝试检查您的数组是否填充了该值,如果已填充,则基于该值构建,否则设置默认值。

$stats = array();
foreach ($dataArray as $element) {
    $obj = $element->to->data[0];
    if (!isset($stats[$obj->id])) { // conditionally create array
        $stats[$obj->id] = array('name'=>$obj->name,'count'=> 0);
    }
    $stats[$obj->id]['count']++; // increment count
}

【讨论】:

  • 有没有办法实现类似于单线 $arr[$obj->id]++but 用于多维数组的东西?我的原始代码与您上面的建议非常相似(它有效),并想看看我是否会丢失几行代码。
  • 刚刚编辑了答案,版本略短,你用“++”增加计数并去掉$count变量。多维数组到底是什么意思,$stats 是多维数组。
【解决方案2】:

$obj = $element->to->data 又是一个数组。如果我正确理解了您的问题,您可能还想遍历 $element->to->data 。所以你的代码现在变成了:

$stats = array();
foreach ($dataArray as $element) {
  $toArray = $element->to->data[0];

  foreach($toArray as $toElement) {

    // check if the key was already created or not
    if(isset($stats[$toElement->id])) {
      $stats[$toElement->id]['count']++;
    }
    else {
      $stats[$toElement->id] = array('name'=>$toArray->name,'count'=>1);
    }
  }
}

更新: 考虑到性能基准,isset() 比 array_key_exists 快得多(但即使值为 null,它也会返回 false!在这种情况下,请考虑一起使用 isset() || array_key exists()

参考:http://php.net/manual/en/function.array-key-exists.php#107786

【讨论】:

  • 有没有办法实现类似于单线$arr[$obj->id]++但用于多维数组的东西?我的原始代码使用了您在上面的建议中显示的isset 函数(它有效),并想看看我是否会丢失几行代码。
  • limeygent 请在multi dimensional 上解释更多。我无法理解你的这部分问题
  • 我更新了我的问题以帮助澄清。我可能会要求一个不受支持的解决方案,并将使用您和 blad 描述的逻辑来实现。
猜你喜欢
  • 1970-01-01
  • 2018-09-12
  • 2019-01-21
  • 1970-01-01
  • 2012-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-04
相关资源
最近更新 更多