我有一个巨大的比较函数,我用它来对具有数字和字符串值的2D数组进行排序,我想让它变小。我已经在彼此内部重复使用了相同的代码块,我认为这是多余的。我想我可以使用递归使代码更小但我认为我之前没有这样做过,而且我的sort函数似乎非常复杂。它如下:
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);
}
我错过了什么?
答案 0 :(得分:0)
我设法解决了问题,并创建了我的第一个递归。
简单地在loop
内调用compare
函数不会做任何事情,因为它会将1
或-1
返回到compare
函数并{{1}函数不会返回任何内容。我需要返回compare
函数返回的值。 loop
成功了。
return loop(a, b, index)
答案 1 :(得分:-1)
我已经在if和switch语句中多次使用相同的代码块,我认为这是多余的。
在尝试跳转到递归之前,首先尝试重构:首先使用Extract Method将重复的代码移动到自己的函数中。