【问题标题】:Problem with an associative array not sorting correctly关联数组未正确排序的问题
【发布时间】:2011-06-24 08:08:31
【问题描述】:

好的,我有一个这样设置的数组:

$buttons = array(
    'home' => array(
        'title' => $txt['home'],
        'href' => $scripturl,
        'show' => true,
        'sub_buttons' => array(
        ),
        'is_last' => $context['right_to_left'],
    ),
    'help' => array(
        'title' => $txt['help'],
        'href' => $scripturl . '?action=help',
        'show' => true,
        'sub_buttons' => array(
        ),
    ),
);

比我在加载后调用一个函数来添加更多按钮并对其进行正确排序,如下所示:

$buttons = load_dream_menu($buttons);

load_dream_menu 函数如下所示:

function load_dream_menu($menu_buttons)
{
    global $smcFunc, $user_info, $scripturl, $context;

    $request = $smcFunc['db_query']('', '
        SELECT *
        FROM {db_prefix}dp_dream_menu
        ORDER BY id_button ASC',
        array(
        )
    );

    $new_menu_buttons = array();

    while ($row = $smcFunc['db_fetch_assoc']($request))
    {
        $permissions = explode(',', $row['permissions']);

        $dp_temp_menu = array(
            'title' => $row['name'],
            'href' => ($row['target'] == 'forum' ? $scripturl : '') . $row['link'],
            'show' => (array_intersect($user_info['groups'], $permissions)) && ($row['status'] == 'active' || (allowedTo('admin_forum') && $row['status'] == 'inactive')),
            'target' => $row['target'],
            'active_button' => false,
        );

        foreach ($menu_buttons as $area => $info)
        {
            if ($area == $row['parent'] && $row['position'] == 'before')
                $new_menu_buttons[$row['slug']] = $dp_temp_menu;

            $new_menu_buttons[$area] = $info;

            if ($area == $row['parent'] && $row['position'] == 'after')
                $new_menu_buttons[$row['slug']] = $dp_temp_menu;

            if ($area == $row['parent'] && $row['position'] == 'child_of')
                $new_menu_buttons[$row['parent']]['sub_buttons'][$row['slug']] = $dp_temp_menu;

            if ($row['position'] == 'child_of' && isset($info['sub_buttons']) && array_key_exists($row['parent'], $info['sub_buttons']))
                $new_menu_buttons[$area]['sub_buttons'][$row['parent']]['sub_buttons'][$row['slug']] = $dp_temp_menu;
        }
    }

    if (!empty($new_menu_buttons))
        $menu_buttons = $new_menu_buttons;

    return $menu_buttons;
}

好的,所以它设法对第一个排序,但在此之后不对另一个排序?我应该在 load_dream_menu 函数的 foreach 循环中使用什么东西吗?类似于使用reset(),但这似乎也不起作用。我在这里做错了什么?请有人帮助我。

所以基本上,我检查数据库,然后循环所有可用的菜单项并将它们添加到另一个数组中,最后,我将原始数组($buttons)设置为新创建的数组。这不应该工作吗?这是我在 load_dream_menu() 函数中执行此操作的地方:

        foreach ($menu_buttons as $area => $info)
        {
            if ($area == $row['parent'] && $row['position'] == 'before')
                $new_menu_buttons[$row['slug']] = $dp_temp_menu;

            $new_menu_buttons[$area] = $info;

            if ($area == $row['parent'] && $row['position'] == 'after')
                $new_menu_buttons[$row['slug']] = $dp_temp_menu;

            if ($area == $row['parent'] && $row['position'] == 'child_of')
                $new_menu_buttons[$row['parent']]['sub_buttons'][$row['slug']] = $dp_temp_menu;

            if ($row['position'] == 'child_of' && isset($info['sub_buttons']) && array_key_exists($row['parent'], $info['sub_buttons']))
                $new_menu_buttons[$area]['sub_buttons'][$row['parent']]['sub_buttons'][$row['slug']] = $dp_temp_menu;
        }

【问题讨论】:

  • 我不确定我是否理解您要执行的操作...如果我做对了,您想在 beforeafter 插入新按钮,还是作为父级的子级?如果是这样,插入逻辑是错误的;你可能想看看array_slice()
  • 是的,这正是我想要做的,它的逻辑有什么问题?
  • 但是如何在关联数组上使用array_slice?有可能吗?
  • 首先,您在 foreach 循环(第一行)中的第一遍将使用所有旧按钮填充 new_menu_buttons。之后,您将失去添加或追加的能力,因为无法在数组中插入之前/之后。

标签: php associative-array sorting


【解决方案1】:

PHP 没有开箱即用的函数来在索引键之后或之前插入元素。

您的功能当前的问题是,当您读取第一行时,您会将所有以前的菜单按钮放回新的菜单按钮中。之后,除了重建数组之外,没有办法在之前或之后插入。我建议编写像

这样的辅助函数
insert_before(array, key, value)
{
    // Splice array in two at key, keeping key on the right side
    // Append new value on the left tail
    // Glue both arrays into a new array
    // Return new array
}
insert_after(array, key, value)
{
    // Symmetric with right & left switched
}

然后您可以在排序例程中使用这些函数。

我发现 this helpful post 关于 PHP 数组中的高效插入。

希望对你有帮助。

【讨论】:

  • 这很好,但你能举个例子说明如何在之前和/或之后执行此操作吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-14
  • 1970-01-01
  • 2011-10-21
  • 2019-04-23
  • 1970-01-01
相关资源
最近更新 更多