快速递归搜索数组中的所有索引

时间:2011-09-28 19:26:28

标签: php arrays

好的,所以说我有一个数组如下:

$buttons = array(
    'mlist' => array(
            'title' => 'Members',
            'href' => $scripturl . '?action=mlist',
            'show' => $context['allow_memberlist'],
            'sub_buttons' => array(
                'mlist_view' => array(
                    'title' => 'View the Member List',
                    'href' => $scripturl . '?action=mlist',
                    'show' => true,
                ),
                'mlist_search' => array(
                    'title' => 'Search for Members',
                    'href' => $scripturl . '?action=mlist;sa=search',
                    'show' => true,
                    'is_last' => true,
                ),
            ),
        ),
    'home' => array(
        'title' => 'Home',
        'href' => $scripturl,
        'show' => true,
        'sub_buttons' => array(
        ),
        'is_last' => $context['right_to_left'],
    ),
    'help' => array(
        'title' => 'Help',
        'href' => $scripturl . '?action=help',
        'show' => true,
        'sub_buttons' => array(
        ),
    ),
);

我需要对这个数组进行排序并将它的所有索引作为索引返回到另一个数组中,这些数组的值将是标题。所以它应该返回一个数组如下:

array(
    'mlist' => 'Members',
    'mlist_view' => 'View the Member List',
    'mlist_search' => 'Search for Members',
    'home' => 'Home',
    'help' => 'Help',
);

如何轻松实现这一目标?基本上,如果指定了标题,则需要每个数组的键,并且需要在另一个数组中填充它们。

4 个答案:

答案 0 :(得分:3)

以下代码片段循环遍历所有数组(递归)以提取键/标题对。

$index    = array();
$iterator = new RecursiveIteratorIterator(new ParentIterator(new RecursiveArrayIterator($buttons)), RecursiveIteratorIterator::SELF_FIRST);
foreach ($iterator as $key => $value) {
    if (array_key_exists('title', $value)) {
        $index[$key] = $value['title'];
    }
}
var_dump($index);

答案 1 :(得分:1)

  

如何轻松实现这一目标?

  1. 初始化一个空的新数组
  2. 使用键和值预先传递$buttons数组
    1. 从值中提取标题
    2. 使用标题
    3. 在新数组中设置密钥
  3. 进行。
  4. 编辑:如果a recursive array iterator catches too much(将元素标识为子元素而不是 - 只是某些其他数组),并且您不希望写一个递归迭代器类的扩展,单步执行所有子代可以用这样的“手写”迭代器来解决:

    $index = array();
    $childKey = 'sub_buttons';
    $iterator = $buttons;
    while(list($key, $item) = each($iterator))
    {
        array_shift($iterator);
        $index[$key] = $item['title'];
        $children = isset($item[$childKey]) ? $item[$childKey] : false;
        if ($children) $iterator = $children + $iterator;
    }
    

    这个迭代器知道子键,所以如果有一些具体的话,它只会遍历子节点。您可以通过更改顺序来控制订单(子项优先,子项最后):

    if ($children) $iterator = $children + $iterator;
    - or - 
    if ($children) $iterator += $children;
    

答案 2 :(得分:0)

我确信我的答案效率不高,但是使用了许多foreach循环,如果检查,可以完成。但是,根据我的解决方案,如果你将'mlist_view'中的另一个数组嵌套起来,你需要从中获取标题,那就不行了。我的解决方案适用于按钮内数组内最多2个数组。更好(更通用的解决方案)可能涉及递归。

$result = array();
foreach($buttons as $field => $value) {
    foreach($value as $nF => $nV) {
        if($nF === 'title') {
            $result[$field] = $nV;
        }
        if(is_array($nV)) {
            foreach($nV as $name => $comp) {
                if(is_array($comp)) {
                    foreach($comp as $nnF => $nnV) {
                        if($nnF === 'title') {
                            $result[$name] = $nnV;
                        }
                    } 
                }
            }
        }
    }
}
foreach($result as $f => $v) {
    echo $f.": ".$v."<br/>";
}

答案 3 :(得分:0)

这适用于你的$按钮的价值,相当简单:

function get_all_keys($arr) {
    if (!is_array($arr)) return array();
    $return = array();
    foreach (array_keys($arr) as $key) {
        if (is_array($arr[$key]) 
            && array_key_exists('title', $arr[$key]))
            $return[$key] = $arr[$key]['title'];
        $return = array_merge($return, get_all_keys($arr[$key]));
    }
    return $return;
}

echo "<pre>";
print_r(get_all_keys($buttons));
echo "</pre>";

返回:

Array
(
    [mlist] => Members
    [mlist_view] => View the Member List
    [mlist_search] => Search for Members
    [home] => Home
    [help] => Help
)