-2

I need to re-order the elements in my array by the number after the "R" and then the first part.

I have a array with the following elements.

215/75R17.5
235/75R17.5
8.25R16
7.00R16
11R22.5
7.50R16

so to this:

7.00R16
7.50R16
8.25R16
11R22.5
215/75R17.5
235/75R17.5
mickmackusa
  • 43,625
  • 12
  • 83
  • 136

2 Answers2

1

First of all this is obviously going to be a custom comparison; the go-to function for that is usort, which accepts a custom comparison as an argument.

The custom comparison function would be like this:

function customCompare($x, $y) {
    $x = explode('R', $x);
    $y = explode('R', $y);
    if ($x[1] != $y[1]) return $x[1] < $y[1] ? -1 : 1;
    return strnatcmp($x[0], $y[0]);
}

See it in action.

How it works

First we split each input string on the character R, producing an array such as ['8.25', '16'] from a string such as '8.25R16'. In each array the second element is the diameter (first sort criterion) and the first is the width (second criterion).

If the diameters are different then we immediately pass judgement based on that.

If the diameters are equal then we use strnatcmp to compare the widths -- this is so that a width of 100 is larger than a width of 20 (a dumb ASCII comparison would produce the opposite result).

Jon
  • 428,835
  • 81
  • 738
  • 806
0

No matter how you decide to isolate the substring that follows R, you should try to minimize the number of times that function calls are made.

Using array_multisort() with mapped calls of the isolating technique will perform better than a usort() approach because usort() will perform the isolating technique multiple times on the same value.

In my snippet below, I do not remove the R while isolating, so I use natural sorting to have the numeric substrings compared correctly. If you aren't familiar with strpbrk() then see this answer for a demonstration.

Code: (Demo)

$array = [
    '215/75R17.5',
    '235/75R17.5',
    '8.25R16',
    '7.00R16',
    '11R22.5',
    '7.50R16'
];

array_multisort(array_map(fn($v) => strpbrk($v, 'R'), $array), SORT_NATURAL, $array);
var_export($array);

An approach that purely isolates the numeric values will not need to sort naturally. (Demo)

array_multisort(array_map(fn($v) => sscanf($v, '%*[^R]R%f')[0], $array), $array);
var_export($array);
mickmackusa
  • 43,625
  • 12
  • 83
  • 136