in Ox.sort(), handle non-leading numbers and leading articles (fixes #723, fixes #779)

This commit is contained in:
rlx 2012-04-24 10:16:58 +00:00
parent 9790e7d6c6
commit 4a210718ea

View file

@ -412,20 +412,21 @@ Ox.range = function() {
function getSortValues(arr, fn) { function getSortValues(arr, fn) {
var arr_ = fn ? arr.map(fn) : arr, var arr_ = fn ? arr.map(fn) : arr,
len, matches = {}, sort = {}; len, matches = {}, sort = {};
// find leading numbers // find numbers
arr.forEach(function(val, i) { arr.forEach(function(val, i) {
var match; var match;
if (Ox.isString(val)) { if (Ox.isString(val)) {
match = /^\d+/.exec(arr_[i]); match = /\d+/.exec(arr_[i]);
matches[val] = match ? match[0] : ''; matches[val] = match ? match[0] : '';
} }
}); });
// get length of longest leading number // get length of longest number
len = Ox.max(Ox.map(matches, function(val) { len = Ox.max(Ox.map(matches, function(val) {
return val.length; return val.length;
})); }));
// pad leading numbers, make lowercase, // pad numbers, make lowercase,
// and remove leading non-word characters // remove leading non-word characters
// and move leading articles to the end
arr.forEach(function(val, i) { arr.forEach(function(val, i) {
var val_ = arr_[i]; var val_ = arr_[i];
if ( if (
@ -442,6 +443,15 @@ Ox.range = function() {
) )
: val_ : val_
).toLowerCase().replace(/^\W+/, ''); ).toLowerCase().replace(/^\W+/, '');
Ox.forEach(['a', 'an', 'the'], function(article) {
var len;
if (new RegExp('^' + article + ' ', 'i').test(sort[val])) {
len = article.length;
sort[val] = sort[val].substr(len + 1) + ', '
+ sort[val].substr(0, len);
return false;
}
});
} else { } else {
sort[val] = val_; sort[val] = val_;
} }
@ -450,7 +460,7 @@ Ox.range = function() {
} }
/*@ /*@
Ox.sort <f> Sorts an array, handling leading digits and ignoring capitalization Ox.sort <f> Sorts an array, handling articles and digits, ignoring capitalization
(arr) -> <a> Sorted array (arr) -> <a> Sorted array
(arr, fn) -> <a> Sorted array (arr, fn) -> <a> Sorted array
arr <a> Array arr <a> Array
@ -459,6 +469,10 @@ Ox.range = function() {
['9', '10', 'a', 'B', '"z"'] ['9', '10', 'a', 'B', '"z"']
> Ox.sort([{id: 0, name: '80 Days'}, {id: 1, name: '8 Women'}], function(v) {return v.name}) > Ox.sort([{id: 0, name: '80 Days'}, {id: 1, name: '8 Women'}], function(v) {return v.name})
[{id: 1, name: '8 Women'}, {id: 0, name: '80 Days'}] [{id: 1, name: '8 Women'}, {id: 0, name: '80 Days'}]
> Ox.sort(['In 80 Days Around the World', 'In 9 Minutes Around the World'])
['In 9 Minutes Around the World', 'In 80 Days Around the World']
> Ox.sort(['Man', 'A Plan', 'The Canal'])
['The Canal', 'Man', 'A Plan']
@*/ @*/
Ox.sort = function(arr, fn) { Ox.sort = function(arr, fn) {
var sort = getSortValues(fn ? arr.map(fn) : arr); var sort = getSortValues(fn ? arr.map(fn) : arr);