Sorting numbers like "6:4" and "16:5" properly

I have a site that has a table full of Biblical references. One columns is the book (Genesis, Mark, Luke, etc) and one is the actual reference (1:15, 16:6), etc.

When a user pulls up the “Mark” page, it then shows all references, sorted by number. The problem is that because it’s not an actual number, it sorts alphabetically which isn’t quite what I want. For example, here’s how a page looks:

1:15
12:44
16:6
6:4

What’s the best way to get them to sort properly, so that the “6:4” reference is between 1:15 and 12:44, where it belongs?

Hey. :slight_smile:

I think this will do it, you have to provide a custom function to apply the sorting logic. Unfortunately, I suck at this type of stuff; but this seems to work.


<?php
$array = array(
  '1:15',
  '6:6',
  '12:44',
  '16:6',
  '6:4',
);

function biblicalSort($a, $b){

  $elements = array(
    'a' => array('chapter' => 0, 'verse' => 0),
    'b' => array('chapter' => 0, 'verse' => 0),
  );

  list($elements['a']['chapter'], $elements['a']['verse'],) = explode(':', $a);
  list($elements['b']['chapter'], $elements['b']['verse'],) = explode(':', $b);

  /* if same chapter, sort by verse*/
  if($elements['a']['chapter'] === $elements['b']['chapter']){
    if($elements['a']['verse'] === $elements['b']['verse']){
      return 0;
    }
    return $elements['a']['verse'] < $elements['b']['verse'] ? -1 : 1 ;
  }

  return $elements['a']['chapter'] < $elements['b']['chapter'] ? -1 : 1 ;
}

usort($array, 'biblicalSort');

print_r(
  $array
);

/*
  Array
  (
    [0] => 1:15
    [1] => 6:4
    [2] => 6:6
    [3] => 12:44
    [4] => 16:6
  )
*/

Heh, failing that. [fphp]natsort[/fphp] appears to sort this natively. Sods law huh. :smiley:


<?php
$array = array(
  '1:15',
  '6:6',
  '12:44',
  '16:6',
  '6:4',
);

natsort($array);

print_r(
  $array
);

/*
  Array
  (
    [0] => 1:15
    [1] => 6:4
    [2] => 6:6
    [3] => 12:44
    [4] => 16:6
  )
*/