Home > OS >  Sort PHP array by numeric portion of an element
Sort PHP array by numeric portion of an element

Time:06-01

PLEASE stop deleting my questions and associating them with previous questions. Those other answers do not solve this specific question.

I have this array:

$elements = ('10 miles', '2 miles', '> 50 miles', '1 mile', '> 500 miles');

How do I sort this by just the numeric portion so I get this:

$elements = ('1 mile', '2 miles', '> 10 miles', '> 50 miles', '> 500 miles');

I have tried this:

$newElements = [];

for each ($elements as $item) {
    $item = preg_replace('/[^0-9]/', '', $item);
    $item = intval($item);  // just in case
    $newElements[] = $item;
}

usort($newElements, 'comp');

function comp($item1, $item2) {
    return $item1 > $item2;
}

But I still get this:

10
25
40
4
60

CodePudding user response:

You can use usort with filter_var function. It works good for you array:

$elements = array('10 miles', '2 miles', '> 50 miles', '1 mile', '> 500 miles');

usort($elements, function($a, $b) {
    return filter_var($a, FILTER_SANITIZE_NUMBER_INT) > filter_var($b, FILTER_SANITIZE_NUMBER_INT);
});


var_dump($elements);

And output should be:

array(5) {
  [0]=>
  string(6) "1 mile"
  [1]=>
  string(7) "2 miles"
  [2]=>
  string(8) "10 miles"
  [3]=>
  string(10) "> 50 miles"
  [4]=>
  string(11) "> 500 miles"
}

CodePudding user response:

You're sorting the array of numbers that you extracted, rather than sorting the original array. You need to extract the number in the comparison function.

function comp($str1, $str2) {
    $num1 = intval(preg_replace('/[^0-9]/', '', $str1));
    $num2 = intval(preg_replace('/[^0-9]/', '', $str2));
    return $num1 - $num2;
}

usort($elements, 'comp');

The comparison function should return a number, not a boolean. The sign of the number indicates which of the inputs is higher.

  • Related