phparrayson-duplicate-keyarray-keyarray-key-exists

Add one increment if same numeric array key exists


I have a following array and i need to sort this array based upon the key value. I wrote a code and got perfect result if all numeric keys are different.

$myarray_need_to_sort =Array
(
    [13] => 214
    [14] => 215
    [15] => 216
    [21] => 223
)

Here is my code

$order = array();
foreach ($myarray_need_to_sort as $value){
    $cat = Mage::getModel('catalog/category')->load($value);
    $order[$cat->getTabOrder()] = $value;
}   
ksort($order);
$sorted_order = array();
foreach ($order as $key=>$value)
{
    $sorted_order[$key] = $value;
}

print_r($sorted_order);

$cat->getTabOrder() is the sort order i am getting from backend and result is perfect

Array
(
    [1] => 216
    [2] => 223
    [3] => 215
    [4] => 214
)

The code is sorting array perfectly but the issue is that if same key exists ie someone added $cat->getTabOrder() same say 2 and 2 for two values then it is removing one key. I need to add one increment for this like

Array
(
    [1] => 216
    [2] => 223
    [2] => 215 -- it should be 3 and 4 should be 5 but it is removing 2 from here
    [4] => 214 -- should be 5
)

Solution

  • As I said in a comment, this looks like an XY problem. You don't actually need to increment the keys, you need to keep all the values (including when the keys are duplicate) and sort them by key.

    I'll assume when two or more items have the same key, the order they come from the database must be kept in the final list.

    The goals are:

    Having this in mind, a possible solution is to keep in $order, for each key the list of items that have that key. Sort the list by keys then either iterate over the array using two nested foreach loops or flatten it before using it.

    The code:

    // $order[$key] is the list of $cat items having $cat->getTabOrder() == $key
    $order = array();
    foreach ($myarray_need_to_sort as $value){
        $cat = Mage::getModel('catalog/category')->load($value);
        $key = $cat->getTabOrder();
        if (! array_key_exists($key, $order)) {
            // This is the first $cat having $key as tab order
            // Create a new list of $key
            $order[$key] = array();
        }
        // Add $value to the list of is $key (tab order)
        $order[$key][] = $value;
    }
    // Sort the outer array by keys
    ksort($order);
    

    A print_r($order) should display something like:

    Array
    (
        [1] => Array
            (
                [0] => 216
            )
        [2] => Array
            (
                [0] => 223
                [1] => 215
            )
        [4] => Array
            (
                [0] => 214
            )
    )
    

    Now, you can retrieve the values from the array by iterating over each sub-array:

    foreach ($order as $key => $list) {
        foreach ($list as $value) {
            echo('$key='.$key.': $value='.$value."\n");
        }
    }
    

    It displays:

    $key=1: $value=216
    $key=2: $value=223
    $key=2: $value=215
    $key=4: $value=214
    

    If you don't care about the keys anymore and all you need is the list of $value after sorting then you can put the values into a new list in the double foreach above (instead of displaying them).

    Or you can write it in a more compact way using array_reduce() and array_merge():

    $new = array_reduce($order, 'array_merge', array());
    print_r($new);
    

    The output is:

    Array
    (
        [0] => 216
        [1] => 223
        [2] => 215
        [3] => 214
    )
    

    Notice that the original keys are lost, the new list is indexed sequentially.