它是可能的,在PHP中,在不使用递归或引用的情况下扁平化(bi/multi)维数组?

我只对值感兴趣,所以键可以忽略,我认为在array_map()和array_values()的行。


当前回答

为了平摊w/o递归(正如您所要求的那样),您可以使用堆栈。当然,你可以把它放到自己的函数中,比如array_flatten。下面是一个使用无键的版本:

function array_flatten(array $array)
{
    $flat = array(); // initialize return array
    $stack = array_values($array); // initialize stack
    while($stack) // process stack until done
    {
        $value = array_shift($stack);
        if (is_array($value)) // a value to further process
        {
            array_unshift($stack, ...$value);
        }
        else // a value to take
        {
            $flat[] = $value;
        }
    }
    return $flat;
}

元素按顺序处理。因为子元素将被移动到堆栈的顶部,所以它们将被下一步处理。

也可以考虑键,但是,您需要不同的策略来处理堆栈。这是必需的,因为您需要处理子数组中可能重复的键。在一个相关的问题中有一个类似的答案:PHP遍历多维数组,同时保留键

我不是特别确定,但我在过去测试过这个:RecurisiveIterator确实使用递归,所以它取决于你真正需要什么。应该可以创建一个基于堆栈的递归迭代器:

foreach(new FlatRecursiveArrayIterator($array) as $key => $value)
{
    echo "** ($key) $value\n";
}

Demo

到目前为止,我还没有实现基于RecursiveIterator的堆栈,我认为这是一个很好的想法。

其他回答

如果你有一个对象数组,想用一个节点把它压平,只需要使用这个函数:

function objectArray_flatten($array,$childField) {
    $result = array();
    foreach ($array as $node)
    {
        $result[] = $node;
        if(isset($node->$childField))
        {
            $result = array_merge(
                $result, 
                objectArray_flatten($node->$childField,$childField)
            );
            unset($node->$childField);
        }

    }
    return $result;
}

如果你想保住你的钥匙,那就是解决办法。

function flatten(array $array) {
    $return = array();
    array_walk_recursive($array, function($value, $key) use (&$return) { $return[$key] = $value; });
    return $return;
}

不幸的是,它只输出最后的嵌套数组,没有中间键。对于下面的例子:

$array = array(
    'sweet' => array(
        'a' => 'apple',
        'b' => 'banana'),
    'sour' => 'lemon'); 
print_r(flatten($fruits));

输出是:

Array
(
    [a] => apple
    [b] => banana
    [sour] => lemon
)

二维数组的解

请试试这个:

$array  = your array

$result = call_user_func_array('array_merge', $array);

echo "<pre>";
print_r($result);

编辑:8月21日-13日

下面是适用于多维数组的解决方案:

function array_flatten($array) {
    $return = array();
    foreach ($array as $key => $value) {
        if (is_array($value)){
            $return = array_merge($return, array_flatten($value));
        } else {
            $return[$key] = $value;
        }
    }

    return $return;
}

$array  = Your array

$result = array_flatten($array);

echo "<pre>";
print_r($result);

裁判:http://php.net/manual/en/function.call-user-func-array.php

使用递归生成器怎么样?https://ideone.com/d0TXCg

<?php

$array = [
    'name' => 'Allen Linatoc',
    'profile' => [
        'age' => 21,
        'favourite_games' => [ 'Call of Duty', 'Titanfall', 'Far Cry' ]
    ]
];

foreach (iterate($array) as $item) {
    var_dump($item);
};

function iterate($array)
{
    foreach ($array as $item) {
        if (is_array($item)) {
            yield from iterate($item);
        } else {
            yield $item;
        }
    }
}

我相信这是最干净的解决方案,不使用任何突变或不熟悉的类。

<?php

function flatten($array)
{
    return array_reduce($array, function($acc, $item){
        return array_merge($acc, is_array($item) ? flatten($item) : [$item]);
    }, []);
}


// usage
$array = [1, 2, [3, 4], [5, [6, 7]], 8, 9, 10];
print_r(flatten($array));