/**
* This is a modified version of sortByRoughSQL_Latin1_General_CP1_CS_AS
* This has a more functional approach, it is more basic
* It simply does a character filter and then sort
* @link https://stackoverflow.com/a/3266430/327074
*
* @param {String} a
* @param {String} b
* @returns {Number} -1,0,1
*/
function latinSqlSort(a, b) {
'use strict';
//--- This is the master lookup table for Latin1 code-points.
// Here through the extended set \u02AF
var latinLookup = [
-1,151,152,153,154,155,156,157,158, 2, 3, 4, 5, 6,159,160,161,162,163,164,
165,166,167,168,169,170,171,172,173,174,175,176, 0, 7, 8, 9, 10, 11, 12,210,
13, 14, 15, 41, 16,211, 17, 18, 65, 69, 71, 74, 76, 77, 80, 81, 82, 83, 19, 20,
42, 43, 44, 21, 22,214,257,266,284,308,347,352,376,387,419,427,438,459,466,486,
529,534,538,559,576,595,636,641,647,650,661, 23, 24, 25, 26, 27, 28,213,255,265,
283,307,346,350,374,385,418,426,436,458,464,485,528,533,536,558,575,594,635,640,
646,648,660, 29, 30, 31, 32,177,178,179,180,181,182,183,184,185,186,187,188,189,
190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,
1, 33, 53, 54, 55, 56, 34, 57, 35, 58,215, 46, 59,212, 60, 36, 61, 45, 72, 75,
37, 62, 63, 64, 38, 70,487, 47, 66, 67, 68, 39,219,217,221,231,223,233,250,276,
312,310,316,318,392,390,395,397,295,472,491,489,493,503,495, 48,511,599,597,601,
603,652,590,573,218,216,220,230,222,232,249,275,311,309,315,317,391,389,394,396,
294,471,490,488,492,502,494, 49,510,598,596,600,602,651,589,655,229,228,227,226,
235,234,268,267,272,271,270,269,274,273,286,285,290,287,324,323,322,321,314,313,
326,325,320,319,358,357,362,361,356,355,364,363,378,377,380,379,405,404,403,402,
401,400,407,406,393,388,417,416,421,420,432,431,428,440,439,447,446,444,443,442,
441,450,449,468,467,474,473,470,469,477,484,483,501,500,499,498,507,506,527,526,
540,539,544,543,542,541,561,560,563,562,567,566,565,564,580,579,578,577,593,592,
611,610,609,608,607,606,613,612,617,616,615,614,643,642,654,653,656,663,662,665,
664,667,666,574,258,260,262,261,264,263,281,278,277,304,292,289,288,297,335,337,
332,348,349,369,371,382,415,409,434,433,448,451,462,476,479,509,521,520,524,523,
531,530,552,572,571,569,570,583,582,581,585,632,631,634,638,658,657,669,668,673,
677,676,678, 73, 79, 78,680,644, 50, 51, 52, 40,303,302,301,457,456,455,482,481,
480,225,224,399,398,497,496,605,604,626,625,620,619,624,623,622,621,334,241,240,
237,236,254,253,366,365,360,359,430,429,505,504,515,514,675,674,422,300,299,298,
354,353, 84, 85, 86, 87,239,238,252,251,513,512,243,242,245,244,328,327,330,329,
411,410,413,412,517,516,519,518,547,546,549,548,628,627,630,629, 88, 89, 90, 91,
92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,
132,133,134,135,136,137,138,139,140,141,142,143,246,247,248,259,279,280,293,291,
339,336,338,331,340,341,342,423,367,373,351,370,372,383,381,384,408,414,386,445,
453,452,454,461,463,460,475,478,465,508,522,525,532,550,553,554,555,545,556,557,
537,551,568,333,424,343,344,586,584,618,633,637,639,645,659,649,670,671,672,679,
681,682,683,282,686,256,345,368,375,425,435,437,535,684,685,305,296,306,591,587,
588,144,145,146,147,148,149,150
];
/**
* A bunch of characters get ignored for the primary sort weight.
* The most important ones are the hyphen and apostrophe characters.
* A bunch of control characters and a couple of odds and ends, make up
* the rest.
*
* @param {Number}
* @returns {Boolean}
* @link https://stackoverflow.com/a/3266430/327074
*/
function ignoreForPrimarySort(iCharCode) {
if (iCharCode < 9) {
return true;
}
if (iCharCode >= 14 && iCharCode <= 31) {
return true;
}
if (iCharCode >= 127 && iCharCode <= 159) {
return true;
}
if (iCharCode == 39 || iCharCode == 45 || iCharCode == 173) {
return true;
}
return false;
}
// normal sort
function compare(a, b) {
return a === b ? 0 : a > b ? 1 : -1;
}
// compare two arrays return first compare difference
function arrayCompare(a, b) {
return a.reduce(function (acc, x, i) {
return acc === 0 && i < b.length ? compare(x, b[i]) : acc;
}, 0);
}
/**
* convert a string to array of latin code point ordering
* @param {String} x
* @returns {Array} integer array
*/
function toLatinOrder(x) {
return x.split('')
// convert to char codes
.map(function(x){return x.charCodeAt(0);})
// filter out ignored characters
.filter(function(x){return !ignoreForPrimarySort(x);})
// convert to latin order
.map(function(x){return latinLookup[x];});
}
// convert inputs
var charA = toLatinOrder(a),
charB = toLatinOrder(b);
// compare the arrays
var charsCompare = arrayCompare(charA, charB);
if (charsCompare !== 0) {
return charsCompare;
}
// fallback to the filtered array length
var charsLenCompare = compare(charA.length, charB.length);
if (charsLenCompare !== 0) {
return charsLenCompare;
}
// Final fallback to a basic length comparison
return compare(a.length, b.length);
}
var tests = [
'Grails Found',
'--Exhibit Visitors',
'-Exhibit Visitors',
'Exhibit Visitors',
'Calls Received',
'Ëxhibit Visitors',
'Brochures distributed',
'exhibit visitors',
'bags of Garbage',
'^&$Grails Found',
'?test',
'612C-520',
'612-C-122',
'612C-122 I',
'612-C-126 L',
'612C-301 B',
'612C-304 B',
'612C-306',
'612-C-306',
'612-C-306 2',
'612-C-403 H',
'612C403 O',
'612-C-403(V)',
'612E-306A/B I',
'612E-306A/B O',
'612C-121 O',
'612C-111 B',
'- -612C-111 B'
].sort(latinSqlSort).join('<br>');
document.write(tests);
所以,從這個問題,你想要的JavaScript來排序,現在的Unicode'統一之前A''-A'? – 2010-07-11 00:42:50
@Bock - 正確,雖然更具體地說,我想要一個與服務器端相匹配的javascript排序算法(我想除了「 - 」字符還有更多要考慮) – DanP 2010-07-11 01:16:00