PHP RecursiveIteratorIterator会覆盖数组键

时间:2014-03-21 07:33:35

标签: php arrays

这是我编写的用于展平多维PHP数组的函数:

function flattenArray(array $array) {
    if (! is_array($array)) {
        throw new Exception ("Please specify an array.");
    }

    $resultArray = [];
    $arrayObject = new RecursiveArrayIterator($array);

    foreach(new RecursiveIteratorIterator($arrayObject) as $key => $value) {
        $resultArray[$key] = $value;
    }

    return $resultArray;
}

使用它:

$arr = [
    ["sitepoint", "phpmaster"],
    ["buildmobile", "rubysource"],
    ["designfestival", "cloudspring"],
    "not an array"
];

print_r(flattenArray($arr));

结果:

Array
(
    [0] => designfestival
    [1] => cloudspring
    [3] => not an array
)

但是,我在期待:

0: sitepoint
1: phpmaster
2: buildmobile
3: rubysource
4: designfestival
5: cloudspring
6: not an array

但它正在重新生成索引,如:

0: sitepoint
1: phpmaster
0: buildmobile
1: rubysource
0: designfestival
1: cloudspring
3: not an array

那么如何修改函数以获取数组的所有元素而不仅仅是三个:

Array
(
    [0] => designfestival
    [1] => cloudspring
    [3] => not an array
)

感谢您的帮助

2 个答案:

答案 0 :(得分:1)

  1. if (!is_array($array))是多余的,因为你在函数签名中有array类型提示,PHP会强制执行。
  2. 正在覆盖密钥。这些元素在各自的子阵列中都具有相同的键。由于它不是关联数组,因此您无需保留键。而不是

    $resultArray[$key] = $value;
    

    只是做

    $resultArray[] = $value;
    

答案 1 :(得分:1)

我也使用RecursiveIteratorIterator来达到这个限制。

起初,我一直在使用这个简洁的单线阵列扁平器:

$outputs = iterator_to_array(new \RecursiveIteratorIterator(new \RecursiveArrayIterator([$inputs])), FALSE);

类似于上面较长的功能。

一切都很棒:我能够将我的数据结构“规范化”为一维数组,无论传入的$ inputs参数是作为单个String / float值,1D还是2 + D多维数组进入我的Symfony2 Controller 。 (我正在编写一个来自AJAX的回调函数,用于回复JSON格式的表格,以便在我的财务应用程序中呈现交互式Highcharts.com图表。)

但是,它拒绝抽奖,因为在最后一步中,每个数据单元都采用

形式
 0 => float 100.662 

即使我注意到我的$输入生物只包含以下形式的单元格:

 '2002-04-30' => float 100.662

所以基本上上面的数组展平线已经杀掉了键(DateStamp)。

厌倦了研究RecursiveIteratorIterator,我刚刚崩溃并想出了我自己的 array_flatten 来保存密钥,如果有的话

static public function array_flatten($inObj)
  {
    $outObj = [];  $inObj=[$inObj];
    array_walk_recursive($inObj, function ($incell, $inkey) use (&$outObj) 
        {
        $outObj[$inkey] = $incell;
        }  );
    return $outObj;
  }

请注意负责确保 $ inObj 中的键全局唯一(以及字符串或int类型),否则,我不知道我的功能如何表现。可能使用相同的密钥名称覆盖该值?