Miger
Miger

Reputation: 1247

Sort flat array by numeric substring in the middle of each string

I want to sort an array of strings where the substring I want to use as sorting identifier is in the middle of the string in question. I've already tried to do that using a very crude technique and I was wondering if there was a better way to do this.

Here is what I've come up with so far:

<?php
$tracks = array(
"Arcane Library_Track2.mp3",
"Deeper Ocean_Track4.mp3"
"Neon Illumination_Track3.mp3",
"Sound Of Cars_Track1.mp3",
);

$tracksreversed = array();
$sortedtracks = array();

foreach( $tracks as $t) {
    array_push( $tracksreversed, strrev($t) ); 
}

sort($tracksreversed);

foreach( $tracksreversed as $t ) {
    array_push( $sortedtracks, strrev($t) );
}

$tracks = $sortedtracks;
?>

This method works but there are two issues. For one it uses two loops and the second problem is that this method will fail as soon as we include more file types like ogg or wav.

Is there a way to easily sort this string according to the _Track1, _Track2, _Track3 indentifiers? Maybe some regex sorting could be done here or perhaps there is some other method I could do which makes this more compact?

Upvotes: 0

Views: 47

Answers (2)

mickmackusa
mickmackusa

Reputation: 47894

Modify my advice on this similar answer to isolate the numbers that trail _Track and use array_multisort() to sort without modifying the original values or declaring additional variables.

Code: (Demo)

array_multisort(
    preg_replace('/.*_Track(\d+)\..*/', '$1', $tracks),
    SORT_NATURAL,
    $tracks
);
var_export($tracks);

Upvotes: 0

Ilia Yatsenko
Ilia Yatsenko

Reputation: 832

Maybe the usort function will be useful. Like:

$getIdx = function(string $name) {
   preg_match('/_Track(?<idx>\d+)/', $name, $matches);
   return $matches['idx'];
};

usort($tracks, function ($a, $b) use ($getIdx) {
   return $getIdx($a) <=> $getIdx($b);
});

Seems to work https://3v4l.org/j65rd

Upvotes: 1

Related Questions