将PHP多维数组的键合并为一个单独的数组?

3

我在PHP中有一个多维数组。它可以动态生成,因此可能具有任意层数。数组中包含的所有数组都不为空,并且都设置了键。

我想找到一种方法将所有数组键值放入一个新数组中。我知道如何在单层数组中执行此操作,但是我卡住了,因为我不知道数组会向多少层深度发展,它本身可以是单层数组或20级多维数组?

谢谢...


数组引用的键应该包含在结果集中吗? - mjhennig
2
在这种情况下,您需要使用递归 - Felix Kling
你只需要键吗?还是需要类似“id”的键,例如top_key和子键top_key-next_key等等? - Jon Egeland
@mjhennig 是的,我想要数组中的每个键,但我不在意相同的键是否会互相覆盖。 - hadley
@Jon 就像这样把数组中的所有键列出来,array('key1', 'key2' ....) - hadley
4个回答

7

对于这个特定的应用程序,我会使用类而不是数组。我这么说的原因是,由于您可以在类中拥有递归函数来访问它,因此处理多个级别将变得更加容易。这是一个我所说的内容的一般示例:

class Node {
    public $children = array();
    public $key;

    public function get_element_by_key($search_key){
        if($this->key == $search_key) return $this;
        foreach ($this->children as &$child) {
            if($child->get_element_by_key($search_key) != NULL){
                return $child;
            }
            else return NULL;
        }
    }
}

您还可以添加函数以添加元素,构造函数以创建元素并添加到父元素等等。然后,您将使用函数get_element_by_key()(或类似函数)访问这些元素。顺便说一下,我没有尝试过此代码,我只是为了说明问题而编写的。但我敢打赌,您可以让它正常工作!


3
$ritit = new RecursiveIteratorIterator(new RecursiveArrayIterator($myArray), RecursiveIteratorIterator::SELF_FIRST);
$keys = array();
foreach ($ritit as $leafValue) {
    foreach (range(0, $ritit->getDepth()) as $depth) {
        $keys[] = $ritit->getSubIterator($depth)->key();
    }
}
print_r(array_unique($keys));

我加入了RecursiveIteratorIterator::SELF_FIRST标志,虽然在这种情况下并不需要(即所有子数组都至少有一个元素的情况)。事实上,在这种情况下,没有这个标志会更有效率。


1

我不确定我完全理解你的问题。如果你想在单维数组中存储多维键,你需要一些编码方式。然后你可以遍历整个“深层”结构,并为每个叶节点将编码键添加到列表中。

如果你只想复制数组,同样适用。你需要遍历数组,在构建副本的同时进行,或者使用深拷贝函数,如PHP引用数组的深拷贝所讨论的。

你可能缺少的部分是,多维数组只是数组的数组。在O'Reilly PHP书籍中有很好的内容。


1
如果您想将所有键作为新数组的值收集起来,以下代码应该适用于您。
// Function to recursively gather keys
function getKeys(&$keyArray, $parentArray) {
    if (!is_array($parentArray) || count($parrentArray) === 0) {
        return;
    }
    foreach ($parentArray as $key => $element) {
        $keyArray[] = $key;
        if (is_array($element)) {
            getKeys($keyArray, $element);
        }
    }
}

// Usage
$arrayToBeChecked = array(array(array(...
$arrayToHoldKeys;
getKeys($arrayToHoldKeys, $arrayToBeChecked);

是的,这就是我想要的。我知道可以用类或其他方式实现,但在我看来,通过引用传递更好,谢谢 :) - hadley
很高兴听到这个消息。但请务必记住类的重要性,人们使用它们是有原因的。另外,如果这是你的“答案”,我会感激你将其标记为答案! - Litty

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接