我需要一个 array_keys_recursive()

Posted

技术标签:

【中文标题】我需要一个 array_keys_recursive()【英文标题】:I need an array_keys_recursive() 【发布时间】:2011-04-21 19:58:12 【问题描述】:
$temp = array();
function show_keys($ar)

    foreach ($ar as $k => $v )
    
        $temp[] = $k;
        if (is_array($ar[$k]))
        
            show_keys ($ar[$k]);
        
    

    return $temp;

我尝试使用该函数,但它仍然只返回第一个键。

【问题讨论】:

这种递归在很多情况下是无限的。 关于风格的说明:不要在全局命名空间中调用变量temptmp尤其是,这会导致混淆。名称应具有描述性;称它为keys,因为这就是它所包含的内容。 【参考方案1】:

您的数组$temp 是全局的。在您需要的功能中可以访问:

global $temp;

在函数的开头。

目前,函数的每次调用都会创建一个名为 $temp 的新数组,当您最终从函数返回给其调用者时,您在第一次调用中创建的 $temp 将被返回,它只有第一级的钥匙。

请注意,使用全局变量并不是好的编程。您需要将数组作为参数传递给递归调用,并通过像 Alexander 和 John 所做的那样添加在每次迭代中找到的键来修改传递的数组。

【讨论】:

没什么区别,好像一开始就接受了$temp。 你可能是对的,这离解决方案又近了一步。【参考方案2】:

主要问题是您丢弃了递归 show_keys() 调用的结果。你不会对返回值做任何事情。

评论是内联的。

function show_keys($ar)

    // Create new temp array inside function so each recursive call gets
    // a separate instance.
    $temp = array();

    foreach ($ar as $k => $v )
    
        $temp[] = $k;

        // Use $v instead of $ar[$k].
        if (is_array($v))
        
            // Combine results of recursive show_keys with $temp.
            $temp = array_merge($temp, show_keys($v));
        
    

    return $temp;

【讨论】:

【参考方案3】:

这样可以解决问题吗?

您必须将 $temp 作为全局变量引入,或者从每个递归中获取返回值。我们希望避免使用全局变量,因此我们将每次递归调用的值与之前收集的值合并。

function show_keys($ar)

    $temp = array();
    foreach ($ar as $k => $v )
    
        $temp[] = $k;
        if (is_array($ar[$k]))
        
            $temp = array_merge(show_keys ($ar[$k]), $temp);
        
    

    return $temp;

【讨论】:

【参考方案4】:

因为这个函数是无限的。但我的任务是帮助你)

function show_keys($ar, $temp = array())
    
    if (!empty($ar)) 
    foreach ($ar as $k => $v )
    
        $temp[] = $k;
        if (is_array($ar[$k]))
        
            $temp += show_keys($ar[$k], $temp);
        
    
    

    return $temp;

【讨论】:

【参考方案5】:

使用 SPL,遍历键非常容易(如果您愿意,可以将它们存储在另一个数组中):

<?php
$arr = array_fill(0,8,range(0,3));
var_dump($arr);
foreach( new RecursiveIteratorIterator(
    new RecursiveArrayIterator($arr),
    RecursiveIteratorIterator::SELF_FIRST)
  as $key => $value)
        var_dump($key);

?>

【讨论】:

【参考方案6】:

我在这里看到了很多过于复杂的解决方案......

function array_keys_r($array) 
  $keys = array_keys($array);

  foreach ($array as $i)
    if (is_array($i))
      $keys = array_merge($keys, array_keys_r($i));

  return $keys;

【讨论】:

【参考方案7】:

问题不明确,因为您没有指定输入和预期输出。

考虑这个示例数组:

$array = [
    'first' => [
        'second' => [
            'third' => 'three',
        ],
        'deuxième' => 'two',
    ],
];

到目前为止,所有其他解决方案都提供了一个扁平的一维键数组列表。

$keys = [
    'first',
    'second',
    'third',
    'deuxième',
];

但是,我需要一个 array_keys_recursive 函数来保留层次结构。

$keys = [
    'first' => [
        'second' => [
            'third',
        ],
        'deuxième',
    ],
];

对于其他寻找类似需求的人,这是我的解决方案:

function array_keys_recursive(array $array) : array

    foreach ($array as $key => $value) 
        if (is_array($value)) 
            $index[$key] = array_keys_recursive($value);
         else 
            $index []= $key;
        
    

    return $index ?? [];

【讨论】:

【参考方案8】:

作为其他解决方案的补充,有可能返回扁平数组,但仍保留有关树的信息。我们可以将嵌套键与父键连接起来。当您区分相同的子键但不同的父键时,这对于与其他数组进行区分可能很有用

function array_keys_flatten_recursive($array, $parentKey = "") 
    $keys = array_keys($array);
    foreach ($array as $parentKey => $i)
      if (is_array($i)) 
        $nestedKeys = array_keys_flatten_recursive($i, $parentKey);
        foreach($nestedKeys as $index => $key) 
            $nestedKeys[$index] = $parentKey . "." . $key;
        
        $keys = array_merge($keys, $nestedKeys);
      
    return $keys;

例子:

$array = array(
    "one" => array(
        "one" => "lorem"
    ),
    "two" => array(
        "one" => "lorem"
    )
);


// result : array("one", "two", "one.one", "two.one")

【讨论】:

以上是关于我需要一个 array_keys_recursive()的主要内容,如果未能解决你的问题,请参考以下文章

我是不是需要重复使用相同的 Akka ActorSystem 或者我可以在每次需要时创建一个?

我需要一个慢速 C# 函数

我需要支持 sql 查询

我需要填充一个选择器

我需要一个定制的移动数字键盘[关闭]

我需要检查一个音符是不是低于 95 并具有功能