1

I want to sort this array by year:

Array
(
    [0] => data/pictures/alice/1980
    [1] => data/pictures/alice/1985
    [2] => data/pictures/bob/1981
    [3] => data/pictures/bob/1985
    [4] => data/pictures/bob/1987
    [5] => data/pictures/bob/1989
)

Expected result:

Array
(
    [0] => data/pictures/alice/1980
    [1] => data/pictures/bob/1981
    [2] => data/pictures/alice/1985
    [3] => data/pictures/bob/1985
    [4] => data/pictures/bob/1987
    [5] => data/pictures/bob/1989
)

I've already tried different sort functions without success.

Example:

asort($paths, SORT_STRING | SORT_FLAG_CASE);

sort($path, SORT_NUMERIC);
1
  • 1
    You want to look at usort(). Commented Oct 16, 2016 at 15:36

4 Answers 4

5

Since it's a path just map the array through basename() and then sort based on that:

array_multisort(array_map('basename', $paths), SORT_ASC, $paths);
Sign up to request clarification or add additional context in comments.

Comments

1

Try this

function cmp($a, $b) {
   // if equal, don't do much
   if ($a == $b) {
       return 0;
   }

   $explodedA = explode('/', $a);
   $explodedB = explode('/', $b);
   $yearPartA = $explodedA[count($explodedA) - 1];
   $yearPartB = $explodedB[count($explodedB) - 1];


   if ($explodedPartA == $explodedPartB) { // compare full string
      return ($a < $b) ? -1 : 1;
   }

   return ($yearPartA < $yearPartB) ? -1 : 1;
}

// actual sort of the array $path (e.g. the whole point)
usort($path, "cmp");

Consider, however that you'd probably be doing 'explode' several times for each array element and that it might be cheaper to work a bit on the array first. Not sure how big your array is... Do some testing.

3 Comments

Show the usort on it :)
Or he could use substr from the position of the last "/" until the end of the string, but it may not be more efficient than exploding.
true... but i'm actually bothered by the part where elements have to be accessed at least once...
0
$array = ['data/pictures/alice/1980','data/pictures/alice/1985','data/pictures/bob/1981','data/pictures/bob/1985','data/pictures/bob/1987','data/pictures/bob/1989'];

uasort($array, function($a,$b) {
    $y1 = array_pop(explode('/', $a));
    $y2 = array_pop(explode('/', $b));
    if($y1===$y2) {
       // if year the same use other criteria
       if($a===$b) {
          return 0;
       }
       return $a>$b?-1:1;
    };
    return $y1>$y2?-1:1;
});

3 Comments

nice touch w/ pop... however,notice the 'problem' when years are the same... i missed it at first, too. for that matter, i think user also missed it when not considering it.
the 'problem' when years are the same - what is the problem?
you added the part where it was a problem, why do u ask then? we can all see history
-1

Use usort and in the custom function explode the strings by "/" and compare the last parts of the arrays.

Comments

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.