Magnanimity Magnanimity - 7 months ago 14
PHP Question

PHP Algorithm for changing the "order" of an array

Scenario:

1) I have a Menu consisting of Menu Items, each with an order_index (ranging from 0 to n), which identifies the Menu Item's position in the Menu.

2) I want to insert a new Menu Item at a specific position or change the position of an existing Element.

3) Assume that if it is a new item, I have already saved the new item in my database with order_index = null.

4) So when editing/creating a menu item, all relevant info other than the order_index gets, saved and then the following function gets called:

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.
*/
}


Example 1: Move Item in position [0] to position [3].
[1] => [0], [2] => [1], [3] => [2], [0] => [3] and all other elements stay the same.

Example 2: Move Item in position [6] to position [3].
Items in position [0],[1] and [2] remain the same. [3] => [4], [4] => [5], [5] => [6], [6] => [3], all other elements stay the same.

I would appreciate any help with an algorithm that would be able to do Steps 2 & 3 for me. Please keep in mind that true genius lies in simplicity. The simpler the algorithm to accomplish this, the better.

A.L A.L
Answer

You can use the built-in PHP functions array_merge() and array_splice(). I think it answers to your question, but the index of the table may be rebuilt by using these functions, I'm not sure it will be a problem for you.

<?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);

Here is the result:

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
)