Normalize array values in natural order PHP

Question

I have faced with the problem, I need to normalize/sort in natural order values in array after some item has been removed.

Consider following example. Initial array

{ [313]=> int(2) [303]=> int(1) [295]=> int(3) [290]=> int(4) }

Sorted array

 { [303]=> int(1) [313]=> int(2) [295]=> int(3) [290]=> int(4) }

Consider case when we are removing first item, array should look like this now

{ [313]=> int(1) [295]=> int(2) [290]=> int(3) }

In case of item inside the array range for example 295 (3) it should be

 { [303]=> int(1) [313]=> int(2) [290]=> int(3) }

I hope you get an idea. But my function doesn't do this correctly. I've implemented part of this sorting, here is the code, but maybe there are other ways to do this easier ?

const MIN_VALUE = 1;
public function sort_items(&$items_map)
{
    if (!empty($items_map)) {
        asort($items_map);
        var_dump($items_map);
        $first_item = reset($items_map);
        if ($first_item > self::MIN_VALUE) {
            $normalize_delta = $first_item - self::MIN_VALUE;
            $prev_item_id = null;
            foreach ($items_map as $id => $part) {
                $items_map[$id] = $part - $normalize_delta;
                if (!empty($prev_item_id)) {
                    $difference = $items_map[$id] - $items_map[$prev_item_id];
                    if ($difference > 1) {
                        $items_map[$id] = $items_map[$id] - ($difference - 1);
                    }
                }
                $prev_item_id = $id;
            }
        }
    }
    return $items_map;
}

I would be grateful for any help.

Thanks

UPDATE

To clarify.

I want items not to be just sorted in the correct order, but to be in natural order, for example

Sequence 1,3,5,6,7,9 should be transformed into 1,2,3,4,5,6 but keeping keys the same.

2,3,7,9 => 1,2,3,4

Please see my example above with real word case.


Show source
| sorting   | php   | arrays   | dictionary   | algorithm   2017-01-02 15:01 1 Answers

Answers ( 1 )

  1. 2017-01-02 16:01

    If you need to use a custom sort algorithm, use usort to do so. From PhP the documentation :

    The comparison function must return an integer less than, equal to, or greater than zero if the first argument is considered to be respectively less than, equal to, or greater than the second.

    So you just need to provide those integers if you are in case an item is "greater" or "lower", and usort will do the job for you.

    In your case, it could lead to this function :

    <?php
        function sort_items_map($a, $b)
        {
            $value = 0;
    
            if( $a < $b )
            {
                $value = -1;
            }
            else if( $a > $b )
            {
                $value = 1;
            }
            else if( $a == $b )
            {
                $value = 0;
            }
    
            return $value;
        }
    
        $items_map = [1, 3, 1, 7]; // or fill it with your own values
    
        usort($items_map, "sort_items_map");
    ?>
    
◀ Go back