上周,也就是2017年2月13日,我问了一个问题。
但这适用于对单列进行排序。当要排序的列的两个元素相同时,它应该能够按另一列对该扇区进行排序,但事实并非如此。
我要排序的数组如下:
var matriz = [
//Columnas: 0 1 2 3 4
/*Filas: 0*/ [9,5,3,2,7],
/* 1*/ [7,9,5,4,3],
/* 2*/ [8,4,6,0,1],
/* 3*/ [9,9,6,2,1]
]
使用当前算法,对第 3列进行排序,答案如下:
var matriz = [
//Columnas: 0 1 2 3 4
/*Filas: 0*/ [7,9,5,4,3],
/* 1*/ [9,5,3,2,7],
/* 2*/ [9,9,6,2,1],
/* 3*/ [8,4,6,0,1]
]
还不错,它是 sorted 4 2 2 0
,但是有2的行应该按我想要的列排序。
确切地说,排序函数应该接收一个数组(一个序列),其中包含我要排序的所有列,例如,[3,0,1,2,4]
. 这意味着首先它按第 3 列排序,如果它们相等(2),它按 0 对它们进行排序,但9也是相同的,所以它按 1 排序,它会被排序,但以防万一按 1、2 和 4 排序。
另外,为了更通用,最好更改列是升序还是降序,为此,它应该是矩阵而不是数组,第一列是要排序的列的编号,第二列column 是一个布尔值,指示true
它是否正在下降,以及false
它是否正在下降。
var columnas = [// Columna - esDescendente
[ 3, true ],
[ 0, true ],
[ 1, true ],
[ 2, false],
[ 4, false]
]
使用此参数,结果应如下所示:
var matriz = [
//Columnas: 0 1 2 3 4
/*Filas: 0*/ [7,9,5,4,3],
/* 1*/ [9,9,6,2,1],
/* 2*/ [9,5,3,2,7],
/* 3*/ [8,4,6,0,1]
]
排序顺序不是静态的,而是由函数生成的。
function generar_compara(columna,esDescendente)
{
var menos=1-2*esDescendente
var devuelve="return a["+columna+"]>=b["+columna+"]?"+menos+":"+(-menos)
return Function("a","b",devuelve)
}
console.log(generar_compara(0,true))
console.log(generar_compara(1,false))
根据我指出的论点,它为我生成了一个不同的标准函数。
0, false
->function anonymous(a,b/**/) {return a[0]>=b[0]?-1:1}
1, true
->function anonymous(a,b/**/) {return a[1]>=b[1]?1:-1}
我的问题是:如果我想订购,标准将如何,例如,如下[3,true],[0,true],[1,true],[2,false],[4,false]
?从示例函数开始,如何构建类似函数的生成器,使其更通用?
一种可能的解决方案是使用递归函数遍历列以查找最大行,如果未找到,则查看下一行。
要控制要检查的列,可以使用与要检查的数组大小相同的控制数组,在循环中根据需要使用或忽略它们的 true 或 false。
例如:
选择列顺序的问题是将地址添加到控制矩阵中,并通过条件递归函数对其进行管理。
标准函数必须遍历数组
columnas
,该数组的每个元素都包含一对值,例如这一行[3,true]
,3
是列,true
是表示它是否是降序的。它应该是这样的:
但是由于该方法
sort
不发送参数columnas
,所以必须用 生成函数Function
,所以我将函数转换为文本字符串,columnas
用插入数组JSON.stringify
。为了能够按不同排序
criterios
,而不是提供一个数组[3,false]
,列在哪里3
并false
指示它是否是ASC o DESC
,在我看来,为了使其更“灵活”,您可以提供一个数组[3,fn]
,其中fn
是一个函数我们将申请对矩阵进行排序。例如:
然后,使用这个“标准”数组,仍然可以应用数组的第一个标准对矩阵进行排序,并根据列值是否在有序行中重复,对它们应用以下标准。
示范:
扩展同一个 OP 的答案,您不需要使用 Function (这是 eval 的一种形式,是不好的做法,并且对读者来说不直观)。您可以通过简单地返回一个函数表达式来实现相同的目的。
同样,它可以表示为: