用于更改数组“顺序”的PHP算法

时间:2014-01-21 11:11:28

标签: php arrays algorithm sorting symfony

场景:

1)我有一个由菜单项组成的菜单,每个菜单项都有一个order_index(范围从0到n),用于标识菜单项在菜单中的位置。
2)我想在特定位置插入新的菜单项或更改现有元素的位置 3)假设如果它是一个新项目,我已经使用order_index = null将新项目保存在我的数据库中。
4)因此,当编辑/创建菜单项时,除了order_index之外的所有相关信息都会被获取,保存,然后调用以下函数:

function reOrderItems(MenuItem $item, Integer $orderIndex)
{
    /*
    Step 1: Retrieve all the MenuItems, ordered by order_index. This means that
            If it was a new item, the item's order_index is null and would be the
            first item in the array of retrieved items.

    Step 2: Take the item ($item) and remove it from its current location in the
            array and place it at its new position, $orderIndex.

    Step 3: "Reorder" the array indexing so that it runs from 0 to
            (array.length - 1) in the order that the Menu Items are now.

    Step 4: Update all items in the database with their new order_index, ranging
            from 0 to n according to the array index.
    */
}

示例1:将项目移动到位置[0]到位置[3]。 [1] => [0],[2] => [1],[3] => [2],[0] => [3]和所有其他元素保持不变。

示例2:将项目移动到位置[6]到位置[3]。 位置[0],[1]和[2]中的项目保持不变。 [3] => [4],[4] => [5],[5] => [6],[6] => [3],所有其他元素保持不变。

对于能够执行第2步和第2步的算法,我将不胜感激。 3对我来说。请记住,真正的天才在于简单。算法越简单越好。

3 个答案:

答案 0 :(得分:0)

检查学说sortable行为(即用型解决方案!)或查看source code的一些想法。

答案 1 :(得分:0)

您可以使用内置的PHP函数array_merge()array_splice()。我认为它回答了你的问题,但是可以通过使用这些函数来重建表的索引,我不确定这对你来说是个问题。

<?php

$menu = array(
    0 => 'Item 1',
    1 => 'Item 2',
    2 => 'Item 3',
    3 => 'Item 4',
    4 => 'Item 5'
);

echo('Default menu:'.PHP_EOL);
print_r($menu);

$menuNewEntry = array(
    0 => 'Item 0 (new)'
);

##### add a menu entry at the beginning #####
$menu = array_merge($menuNewEntry, $menu);

echo('Default menu with new entry:'.PHP_EOL);
print_r($menu);

##### remove a menu entry #####
array_splice($menu, 2, 1);

echo('Default menu without entry at index 2:'.PHP_EOL);
print_r($menu);

##### move a menu entry #####
# remove an element from the array and keep the result (the removed element)
$menuRemovedEntry = array_splice($menu, 0, 1);

# insert this element in the array (the removed element)
array_splice($menu, 2, 0, $menuRemovedEntry);

echo('Default menu with entry 0 moved at index 2:'.PHP_EOL);
print_r($menu);

结果如下:

Default menu:
Array
(
    [0] => Item 1
    [1] => Item 2
    [2] => Item 3
    [3] => Item 4
    [4] => Item 5
)
Default menu with new entry:
Array
(
    [0] => Item 0 (new)
    [1] => Item 1
    [2] => Item 2
    [3] => Item 3
    [4] => Item 4
    [5] => Item 5
)
Default menu without entry at index 2:
Array
(
    [0] => Item 0 (new)
    [1] => Item 1
    [2] => Item 3
    [3] => Item 4
    [4] => Item 5
)
Default menu with entry 0 moved at index 2:
Array
(
    [0] => Item 1
    [1] => Item 3
    [2] => Item 0 (new)
    [3] => Item 4
    [4] => Item 5
)

答案 2 :(得分:0)

查看reorder中的Nspl功能:

use function nspl\a\reorder;

$menu = array(
    0 => 'Item 0',
    1 => 'Item 1',
    2 => 'Item 2',
    3 => 'Item 3',
    4 => 'Item 4',
    5 => 'Item 5',
    6 => 'Item 6',
);

echo "Example 1\n";
print_r(reorder($menu, 0, 3));

echo "\nExample 2\n";
print_r(reorder($menu, 6, 3));

输出:

Example 1
Array
(
    [0] => Item 1
    [1] => Item 2
    [2] => Item 3
    [3] => Item 0
    [4] => Item 4
    [5] => Item 5
    [6] => Item 6
)

Example 2
Array
(
    [0] => Item 0
    [1] => Item 1
    [2] => Item 2
    [3] => Item 6
    [4] => Item 3
    [5] => Item 4
    [6] => Item 5
)