我有一個巨大的比較函數,我正在使用數字和字符串值對二維數組進行排序,並且我想讓它變小。我已經在對方內部重複使用了相同的代碼塊,我認爲這是多餘的。我想我可以使用遞歸來縮小代碼,但是我不認爲我之前做過這些,而且我的排序功能似乎非常複雜。這是如下:排序函數中的遞歸
check if a & b is array
check if a & b is number or string
if number
check if a equals to b
repeat same process with different index
if string
check if a equals to b
repeat same process with different index
一個例子數組:
var artists = [
["Katy Perry", "3", "9" ],
["Enrique Iglesias", "3", "9" ],
["Taylor Swift", "2", "9" ],
["Evanescence", "4", "10" ],
["Bruno Mars", "1", "5" ],
["Shania Twain", "3", "12" ],
["Amanda Abizaid", "2", "2" ],
["Death Cab For Cutie", "2", "2" ],
["Simple Plan", "1", "2" ],
];
// sort and prioritize columns by 2, 1, 0, sort order for each 1 = asc
artists.sort(compare.bind([2, 1, 0], [1, 1, 1]));
排序後的同一個陣列:
var artists = [
["Simple Plan", "1", "2" ],
["Amanda Abizaid", "2", "2" ],
["Death Cab For Cutie", "2", "2" ],
["Bruno Mars", "1", "5" ],
["Taylor Swift", "2", "9" ],
["Enrique Iglesias", "3", "9" ],
["Katy Perry", "3", "9" ],
["Evanescence", "4", "10" ],
["Shania Twain", "3", "12" ],
];
實際比較功能:
// compare is passed to Array.prototype.sort
// array2bSorted.sort(sortable.compare.bind([cols, orders]));
compare : function(a, b) {
var columns = sortable.explodeInnerArrays(this[0]);
var orders = sortable.explodeInnerArrays(this[1]);
var primaryA = a[columns[0]];
var primaryB = b[columns[0]];
if (primaryA instanceof Array) {
primaryA = a[columns[0]][0];
}
if (primaryB instanceof Array) {
primaryB = b[columns[0]][0];
}
switch (sortable.checkDataType(primaryA)) {
case "number":
if (primaryA == primaryB && columns.length > 1) {
var secondaryA = a[columns[1]];
var secondaryB = b[columns[1]];
if (secondaryA instanceof Array) {
secondaryA = a[columns[1]][0];
}
if (secondaryB instanceof Array) {
secondaryB = b[columns[1]][0];
}
switch (sortable.checkDataType(secondaryA)) {
case "number":
if (secondaryA == secondaryB && columns.length > 2) {
var tertiaryA = a[columns[2]];
var tertiaryB = b[columns[2]];
if (tertiaryA instanceof Array) {
tertiaryA = a[columns[2]][0];
}
if (tertiaryB instanceof Array) {
tertiaryB = b[columns[2]][0];
}
switch (sortable.checkDataType(tertiaryA)) {
case "number":
return (tertiaryA - tertiaryB) * orders[2];
break;
case "string":
tertiaryA = sortable.removePunctuation(tertiaryA);
tertiaryB = sortable.removePunctuation(tertiaryB);
if (tertiaryA < tertiaryB) {
return -1 * orders[2];
}
if (tertiaryA > tertiaryB) {
return 1 * orders[2];
}
return 0;
break;
}
}
return (secondaryA - secondaryB) * orders[1];
break;
case "string":
if (secondaryA == secondaryB && columns.length > 2) {
var tertiaryA = a[columns[2]];
var tertiaryB = b[columns[2]];
if (tertiaryA instanceof Array) {
tertiaryA = a[columns[2]][0];
}
if (tertiaryB instanceof Array) {
tertiaryB = b[columns[2]][0];
}
switch (sortable.checkDataType(tertiaryA)) {
case "number":
return (tertiaryA - tertiaryB) * orders[2];
break;
case "string":
tertiaryA = sortable.removePunctuation(tertiaryA);
tertiaryB = sortable.removePunctuation(tertiaryB);
if (tertiaryA < tertiaryB) {
return -1 * orders[2];
}
if (tertiaryA > tertiaryB) {
return 1 * orders[2];
}
return 0;
break;
}
}
secondaryA = sortable.removePunctuation(secondaryA);
secondaryB = sortable.removePunctuation(secondaryB);
if (secondaryA < secondaryB) {
return -1 * orders[1];
}
if (secondaryA > secondaryB) {
return 1 * orders[1];
}
break;
}
}
return (primaryA - primaryB) * orders[0];
break;
case "string":
if (primaryA == primaryB && columns.length > 1) {
var secondaryA = a[columns[1]];
var secondaryB = b[columns[1]];
if (secondaryA instanceof Array) {
secondaryA = a[columns[1]][0];
}
if (secondaryB instanceof Array) {
secondaryB = b[columns[1]][0];
}
switch (sortable.checkDataType(secondaryA)) {
case "number":
if (secondaryA == secondaryB) {
var tertiaryA = a[columns[2]];
var tertiaryB = b[columns[2]];
if (tertiaryA instanceof Array) {
tertiaryA = a[columns[2]][0];
}
if (tertiaryB instanceof Array) {
tertiaryB = b[columns[2]][0];
}
switch (sortable.checkDataType(tertiaryA)) {
case "number":
return (tertiaryA - tertiaryB) * orders[2];
break;
case "string":
tertiaryA = sortable.removePunctuation(tertiaryA);
tertiaryB = sortable.removePunctuation(tertiaryB);
if (tertiaryA < tertiaryB) {
return -1 * orders[2];
}
if (tertiaryA > tertiaryB) {
return 1 * orders[2];
}
return 0;
break;
}
}
return (secondaryA - secondaryB) * orders[1];
break;
case "string":
if (secondaryA == secondaryB && columns.length > 2) {
var tertiaryA = a[columns[2]];
var tertiaryB = b[columns[2]];
if (tertiaryA instanceof Array) {
tertiaryA = a[columns[2]][0];
}
if (tertiaryB instanceof Array) {
tertiaryB = b[columns[2]][0];
}
switch (sortable.checkDataType(tertiaryA)) {
case "number":
return (tertiaryA - tertiaryB) * order;
break;
case "string":
tertiaryA = sortable.removePunctuation(tertiaryA);
tertiaryB = sortable.removePunctuation(tertiaryB);
if (tertiaryA < tertiaryB) {
return -1 * orders[2];
}
if (tertiaryA > tertiaryB) {
return 1 * orders[2];
}
return 0;
break;
}
}
secondaryA = sortable.removePunctuation(secondaryA);
secondaryB = sortable.removePunctuation(secondaryB);
if (secondaryA < secondaryB) {
return -1 * orders[1];
}
if (secondaryA > secondaryB) {
return 1 * orders[1];
}
break;
}
}
primaryA = sortable.removePunctuation(primaryA);
primaryB = sortable.removePunctuation(primaryB);
if (primaryA < primaryB) {
return -1 * orders[0];
}
if (primaryA > primaryB) {
return 1 * orders[0];
}
break;
}
},
比較函數對數組由多列組成每個都有自己的排序順序。由於列以數組形式傳遞,因此初始索引具有更高的優先級。
使用遞歸我已經想出了下面的代碼,但它不工作。數組未排序。它也不會拋出任何錯誤。 (我刪除了一些不相關的部分,使它看起來更簡單)
compare : function(a, b) {
var columns = sortable.explodeInnerArrays(this[0]);
var orders = sortable.explodeInnerArrays(this[1]);
function loop(a, b, index) {
var currentA = a[columns[index]];
var currentB = b[columns[index]];
switch (sortable.checkDataType(currentA)) {
case "number":
if (currentA == currentB) {
loop(a, b, (index+1));
}
return (currentA - currentB) * orders[index];
break;
case "string":
if (currentA == currentB) {
loop(a, b, (index+1));
}
if (currentA < currentB) {
return -1 * orders[index];
}
if (currentA > currentB) {
return 1 * orders[index];
}
break;
}
}
loop(a,b,0);
}
我缺少什麼?
是的,明確的。遞歸或循環。無論如何,您需要支持3列以上。你試過了嗎? – Bergi
@Bergi是的,仍然在努力。嘗試遞歸。我不知道我會如何去循環。 – akinuri
如果這不僅僅是爲了教育目的,爲什麼不使用Array.prototype.sort()方法?這是從IE> = 5.5支持的,當然也支持所有現代Web瀏覽器。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort –