PHP - 需要帮助将数组插入到给定键的关联数组中

Posted

技术标签:

【中文标题】PHP - 需要帮助将数组插入到给定键的关联数组中【英文标题】:PHP - Need help inserting arrays into Associative arrays at given keys 【发布时间】:2011-09-24 00:23:37 【问题描述】:

好的,所以我有一个这样的数组:

$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(
        ),
    ),
    'search' => array(
        'title' => $txt['search'],
        'href' => $scripturl . '?action=search',
        'show' => $context['allow_search'],
        'sub_buttons' => array(
        ),
    ),
    'admin' => array(
        'title' => $txt['admin'],
        'href' => $scripturl . '?action=admin',
        'show' => $context['allow_admin'],
        'sub_buttons' => array(
            'featuresettings' => array(
                'title' => $txt['modSettings_title'],
                'href' => $scripturl . '?action=admin;area=featuresettings',
                'show' => allowedTo('admin_forum'),
            ),
            'packages' => array(
                'title' => $txt['package'],
                'href' => $scripturl . '?action=admin;area=packages',
                'show' => allowedTo('admin_forum'),
            ),
            'errorlog' => array(
                'title' => $txt['errlog'],
                'href' => $scripturl . '?action=admin;area=logs;sa=errorlog;desc',
                'show' => allowedTo('admin_forum') && !empty($modSettings['enableErrorLogging']),
            ),
            'permissions' => array(
                'title' => $txt['edit_permissions'],
                'href' => $scripturl . '?action=admin;area=permissions',
                'show' => allowedTo('manage_permissions'),
                'is_last' => true,
            ),
        ),
    ),
    'moderate' => array(
        'title' => $txt['moderate'],
        'href' => $scripturl . '?action=moderate',
        'show' => $context['allow_moderation_center'],
        'sub_buttons' => array(
            'modlog' => array(
                'title' => $txt['modlog_view'],
                'href' => $scripturl . '?action=moderate;area=modlog',
                'show' => !empty($modSettings['modlog_enabled']) && !empty($user_info['mod_cache']) && $user_info['mod_cache']['bq'] != '0=1',
            ),
            'poststopics' => array(
                'title' => $txt['mc_unapproved_poststopics'],
                'href' => $scripturl . '?action=moderate;area=postmod;sa=posts',
                'show' => $modSettings['postmod_active'] && !empty($user_info['mod_cache']['ap']),
            ),
            'attachments' => array(
                'title' => $txt['mc_unapproved_attachments'],
                'href' => $scripturl . '?action=moderate;area=attachmod;sa=attachments',
                'show' => $modSettings['postmod_active'] && !empty($user_info['mod_cache']['ap']),
            ),
            'reports' => array(
                'title' => $txt['mc_reported_posts'],
                'href' => $scripturl . '?action=moderate;area=reports',
                'show' => !empty($user_info['mod_cache']) && $user_info['mod_cache']['bq'] != '0=1',
                'is_last' => true,
            ),
        ),
    ),
    'profile' => array(
        'title' => $txt['profile'],
        'href' => $scripturl . '?action=profile',
        'show' => $context['allow_edit_profile'],
        'sub_buttons' => array(
            'summary' => array(
                'title' => $txt['summary'],
                'href' => $scripturl . '?action=profile',
                'show' => true,
            ),
            'account' => array(
                'title' => $txt['account'],
                'href' => $scripturl . '?action=profile;area=account',
                'show' => allowedTo(array('profile_identity_any', 'profile_identity_own', 'manage_membergroups')),
            ),
            'profile' => array(
                'title' => $txt['forumprofile'],
                'href' => $scripturl . '?action=profile;area=forumprofile',
                'show' => allowedTo(array('profile_extra_any', 'profile_extra_own')),
                'is_last' => true,
            ),
        ),
    ),
    'pm' => array(
        'title' => $txt['pm_short'],
        'href' => $scripturl . '?action=pm',
        'show' => $context['allow_pm'],
        'sub_buttons' => array(
            'pm_read' => array(
                'title' => $txt['pm_menu_read'],
                'href' => $scripturl . '?action=pm',
                'show' => allowedTo('pm_read'),
            ),
            'pm_send' => array(
                'title' => $txt['pm_menu_send'],
                'href' => $scripturl . '?action=pm;sa=send',
                'show' => allowedTo('pm_send'),
                'is_last' => true,
            ),
        ),
    ),
    'calendar' => array(
        'title' => $txt['calendar'],
        'href' => $scripturl . '?action=calendar',
        'show' => $context['allow_calendar'],
        'sub_buttons' => array(
            'view' => array(
                'title' => $txt['calendar_menu'],
                'href' => $scripturl . '?action=calendar',
                'show' => allowedTo('calendar_post'),
            ),
            'post' => array(
                'title' => $txt['calendar_post_event'],
                'href' => $scripturl . '?action=calendar;sa=post',
                'show' => allowedTo('calendar_post'),
                'is_last' => true,
            ),
        ),
    ),
    'mlist' => array(
        'title' => $txt['members_title'],
        'href' => $scripturl . '?action=mlist',
        'show' => $context['allow_memberlist'],
        'sub_buttons' => array(
            'mlist_view' => array(
                'title' => $txt['mlist_menu_view'],
                'href' => $scripturl . '?action=mlist',
                'show' => true,
            ),
            'mlist_search' => array(
                'title' => $txt['mlist_search'],
                'href' => $scripturl . '?action=mlist;sa=search',
                'show' => true,
                'is_last' => true,
            ),
        ),
    ),
    'login' => array(
        'title' => $txt['login'],
        'href' => $scripturl . '?action=login',
        'show' => $user_info['is_guest'],
        'sub_buttons' => array(
        ),
    ),
    'register' => array(
        'title' => $txt['register'],
        'href' => $scripturl . '?action=register',
        'show' => $user_info['is_guest'],
        'sub_buttons' => array(
        ),
        'is_last' => !$context['right_to_left'],
    ),
    'logout' => array(
        'title' => $txt['logout'],
        'href' => $scripturl . '?action=logout;%1$s=%2$s',
        'show' => !$user_info['is_guest'],
        'sub_buttons' => array(
        ),
        'is_last' => !$context['right_to_left'],
    ),
);

现在我希望能够在上面数组中的任何键之前或之后插入一个数组。我要插入的数组可以是这样的:

$new_menu_buttons['testing'] = array(
    'title' => $txt['testing'],
    'href' => $scripturl . '?action=testing',
    'show' => true,
    'target' => '_self',
    'active_button' => false,
);

有人推荐了处理这个问题的函数和使用方法,但我不知道该怎么做,他们也想要这些函数的偏移量。这是有人推荐我使用的函数结构,而不是在需要时调用这些函数:

function array_insert_before($array, $key, $new_array)

    // 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

function array_insert_after($array, $key, $new_array)

    // Symmetric with right & left switched

所以,我希望能够像这样调用函数:

如果它需要在键之后,指定的'home':

$menu_buttons = array_insert_after($buttons, 'home', $new_menu_buttons);

如果它需要在键之前,指定的'home':

$menu_buttons = array_insert_before($buttons, 'home', $new_menu_buttons);

基本上,我真的需要这些功能的帮助,任何帮助都会很棒。

我应该使用array_splice 还是array_slice?请问有人愿意用一些实际的代码让我朝着正确的方向开始吗?

谢谢大家:)

【问题讨论】:

在创建导航之前引入位置值并对其进行排序不是更容易吗?或者使用 SplHeap 或 PriorityQueue 来保持导航有序? 如果你觉得这个问题已经被回答了,那么你应该把它标记为已回答(检查评分下的按钮以获得答案)。 【参考方案1】:

这应该可以帮助您入门。注意:我没有测试过这个。没想到吧。

/**
 * This will insert $new at the beginning if $key is not found
 */
function array_insert_before($array, $key, $new)

    $keys = array_keys($array);
    $pos = (int) array_search($key, $keys);
    return array_merge(
        array_slice($array, 0, $pos),
        $new,
        array_slice($array, $pos)
    );

array_insert_after() 几乎相同,除了$pos 加一。你应该能够自己弄清楚。

【讨论】:

@Sander Marechal - 您可以使用return array_splice($array, $position, 0, $new);,而不是使用您的return array_merge(...) 调用。如果length 参数设置为0,它将插入offset 之后,其余部分保持不变。 你好 Sander,$key 总会被找到,因为这是来自同一个 $array 的键,它不是用户输入的。但它需要这样,因为我需要在创建数组之后在数组中执行此操作。谢谢会试一试,看看这是否对我有帮助。 SoLoGHoST - return array_merge(...) 调用了两次array_slice,所以总共调用了 3 个函数。您可以将其替换为我在第一条评论中所写的内容(return array_splice(...))。为了回答您对@Sander Marechal 的评论,array_search 正在搜索数组中键的位置,而不是它是否存在。 array_slicearray_splice 都需要知道位置而不是密钥。 @SoLoGHoSt - 该行实际上应该包含return。它应该在下一行返回(return $array);另一件事是在上面@Sander Marechal 的代码中,array_search($keys, $key) 应该是array_search($key, $keys); @Sander Marechal - array_splice 不起作用,我认为这是因为 array_splice 函数中的 replacement 参数不保留 $new 数组的键。你让它工作的方式完美,除了你应该有array_search($key, $keys;)。我使用了你的方法,并在下面的答案中更好地适应了我的需要。【参考方案2】:

好的,在玩了一段时间之后,我终于让它按照我想要的方式工作了。我正在使用 $new_menu_buttons 中的某些键来决定要做什么。例如: position 告诉我它是在之后还是之前,parent 告诉我在哪里搜索键,slug 给我用于添加的每个新菜单数组的键。 array_splice 不适合我,所以我使用 array_merge 方法,效果很好。这是为其他遇到此问题的人准备的。

function array_insert_buttons($buttons, $new_menu_buttons)

    foreach($new_menu_buttons as $new)
    
        $keys = array_keys($buttons);
        $position = (int)array_search($new['parent'], $keys);

        if ($new['position'] == 'after')
            $position = $position + 1;

        // Create the new array in the correct format, using the slug!
        $new_button = array();
        $new_button[$new['slug']] = $new;

        // Don't need these keys anymore.
        unset($new_button[$new['slug']]['position']);
        unset($new_button[$new['slug']]['parent']);
        unset($new_button[$new['slug']]['slug']);

        // Putting it all together now.
        $buttons = array_merge(
            array_slice($buttons, 0, $position),
            $new_button,
            array_slice($buttons, $position)
        );
    

    return $buttons;

感谢你们的帮助:)

【讨论】:

以上是关于PHP - 需要帮助将数组插入到给定键的关联数组中的主要内容,如果未能解决你的问题,请参考以下文章

如何将文本附加到特定的php数组值

PHP树-不需要递归

如何从关联数组中删除键及其值?

将php数组插入mySql

使用 PHP 将 XML 转换为关联数组

php 数组索引值如何重新从0开始递增