0

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]
) 

2 Answers 2

1

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);
Sign up to request clarification or add additional context in comments.

Comments

1

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]);
}

2 Comments

That only takes the numeric part before "-" into account. If that is your desired behaviour, your original question should mention it.
@simon.ro How would you do to sort by the whole reference?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.