Home > other >  How can I sort a multidimensional array by an alphanumeric value but only by the numeric part?
How can I sort a multidimensional array by an alphanumeric value but only by the numeric part?

Time:12-21

I need to sort a multidimensional array by a the column reference. The problem is that the reference has '-', so reference is alphanumeric.

Example:

array(
  0 =>['other_value' => y, 'reference' => '423-52', 'other_value' => x],
  1 =>['other_value' => y, 'reference' => '223-52', 'other_value' => x],
  2 =>['other_value' => y, 'reference' => '5423-52', 'other_value' => x],
  3 =>['other_value' => y, 'reference' => '823-52', 'other_value' => x],
  4 =>['other_value' => y, 'reference' => '123-52', 'other_value' => x]
) 

Expected sorted result:

array(
  0 =>['other_value' => y, 'reference' => '123-52', 'other_value' => x],
  1 =>['other_value' => y, 'reference' => '223-52', 'other_value' => x],
  2 =>['other_value' => y, 'reference' => '423-52', 'other_value' => x],
  3 =>['other_value' => y, 'reference' => '823-52', 'other_value' => x],
  4 =>['other_value' => y, 'reference' => '5423-52', 'other_value' => x]
) 

CodePudding user response:

Finally, I use the function usort to call a method which has a comparing function (gmp_cmp) exploded by '-' and getting the first position, but this method only sort by the reference first part.

usort($products, array('Method file', "cmp_numeric"));

public static function cmp_numeric($a, $b)
{
  return gmp_cmp(explode('-', $a["reference"])[0], explode('-', $b["reference"])[0]);
}

CodePudding user response:

Using filter_var with FILTER_SANITIZE_NUMBER_INT to transform value to (positive/negative) integer value, and the spaceship operator <=> for comparison.

See the code in action at https://3v4l.org/OZ7VD

<?php
$payload = [
    ['other_value_y' => 'y', 'reference' => '423-52', 'other_value_x' => 'x'],
    ['other_value_y' => 'y', 'reference' => '223-52', 'other_value_x' => 'x'],
    ['other_value_y' => 'y', 'reference' => '5423-52', 'other_value_x' => 'x'],
    ['other_value_y' => 'y', 'reference' => '823-52', 'other_value_x' => 'x'],
    ['other_value_y' => 'y', 'reference' => '123-52', 'other_value_x' => 'x'],
];

usort($payload, static function (array $a, array $b) {
    if (!isset($a['reference']) || !isset($b['reference'])) {
        throw new \RuntimeException('Missing array key "reference"', 1671615426);
    }
    // "Remove all characters except digits, plus and minus sign."
    // (consequence `-123-45-67` is treated as (negative) `-1234567`)
    // sse https://www.php.net/manual/en/filter.filters.sanitize.php
    return filter_var($a['reference'], FILTER_SANITIZE_NUMBER_INT)
        <=> filter_var($b['reference'], FILTER_SANITIZE_NUMBER_INT);
});

print_r($payload);
  • Related