【问题标题】:PHP - RecursiveArrayIterator recurse on all but last levelPHP - RecursiveArrayIterator 在除最后一级之外的所有级别上递归
【发布时间】:2015-06-21 15:18:30
【问题描述】:

我需要展平一个多维数组,但不展平最后一层。

例如,考虑下面的数组

$array = [
    1 => [
        1 => [
            'anna',
            'alice'
        ],
        2 => [
            'bob',
            'bartold'
        ]
    ],
    2 => [
        1 => [
            'carol'
        ],
        2 => [
            'david'
        ]
    ]
];

以下代码

$result = [];

$iterator = new \RecursiveIteratorIterator(
    new \RecursiveArrayIterator($array)
);

foreach ($iterator as $row) {
    $result[] = $row;
}

返回以下数组

array(6) {
  [0]=>
  string(4) "anna"
  [1]=>
  string(5) "alice"
  [2]=>
  string(3) "bob"
  [3]=>
  string(7) "bartold"
  [4]=>
  string(5) "carol"
  [5]=>
  string(5) "david"
}

我想要得到的是以下内容:

[
    1 => [
        'anna',
        'alice'
    ],
    2 => [
        'bob',
        'bartold'
    ],
    3 => [
        'carol'
    ],
    4 => [
        'david'
    ]
];

没有展平数组的最后一层。 有没有简单的方法来获得这个?

可能我想使用迭代器。

如果您愿意,可以尝试使用this

【问题讨论】:

  • 您尝试过使用 array_walk_recursive 吗? php.net/manual/en/function.array-walk-recursive.php
  • @briosheje 是的,我试过了,结果与我发布的代码完全相同
  • 得不到你想要的有两个原因:1)节点[1]的嵌套逻辑与节点[2]不同。 2)您以某种方式分配了无法在递归循环中逻辑重新创建的新键(输出中的键 1、2、3、4),因为它是递归的。我个人建议你要么执行一个嵌套的 foreach 循环,要么只实现一个 ad-hoc 函数。

标签: php arrays recursion iterator


【解决方案1】:

您可以递归地展平数组,同时在每个元素上向前看,如果它包含子数组并基于它更改合并:

<?php

function flattenArrayWithLookAhead($include = array()) {
  $new = array();

  foreach($include as $item) {
    if(is_array($item)) {
      $containsArrays = array_reduce($item, function ($carry, $current) {
        if(is_array($current) || $carry === true) return true;
        else return false;
      });

      if($containsArrays) $new = array_merge($new, flattenArrayWithLookAhead($item));
      else $new[] = $item;
    } else {
      $new[] = $item;
    }
  }

  return $new;
}

$array = flattenArrayWithLookAhead($array);

online TEST

(注意:我确信函数可以简化,但我对递归函数的喜爱目前处于最低限度。)

【讨论】:

    【解决方案2】:

    请记住,递归迭代器总是遍历数据结构以返回数据节点,而不是前面的结构。为了保持结构,你可以做一个嵌套的foreach

    $newdata = array();
    foreach($data as $group) {
        foreach($group as $set) {
            $newdata[] = $set;
        }
    }
    

    【讨论】:

    • 嵌套 foreach 的问题是,如果我需要在根附近添加嵌套级别,我的代码将不再工作。我想唯一的解决方案是使用递归函数
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-30
    • 2012-09-21
    • 2012-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-24
    相关资源
    最近更新 更多