要求是按resHP 属性升序排序,然后对于任何平局,按resFlow 属性降序排序。
现在,Javascript 的Array.prototype.sort 函数允许我们对数组进行排序。它接受一个参数,即 "compareFunction"。 compareFunction 接受两个参数,它们是要比较的数组的元素,它必须返回它们在预期结果数组中的相对位置。
function compareFunction (itemA, itemB) {...}
如果b 在结果中位于a 之前,
compareFunction(a, b) 返回一个数值大于零。
如果b 在结果中位于a 之后,则
compareFunction(a, b) 返回一个数值小于零。
如果a 和b 在对数组进行排序时在相对顺序方面被认为是等效的,则compareFunction(a, b) 返回零。例如,在对[5, 3, 5] 进行排序时,两个 5 被认为是等效的,因此当调用 compareFunction(5,5) 时数组应该返回 0。
对于字符串排序,不需要提供compareFunction。按照规范,当不提供 compareFunction 时,数组中的每个值都会转换为字符串,然后进行排序。这是一个例子:
console.log('["z", "ct", "a", "aa", "ab", "bc"].sort(): ', ["z", "ct", "a", "aa", "ab", "bc"].sort());
常见错误:
不使用 compareFunction 比较数字
虽然 compareFunction 按规范是可选的,但如果在对数字或其他对象进行排序时未提供,可能会导致结果不正确。考虑下面的例子:
console.log("[1, 2, 5, 3, 0, 20].sort(): ", [1, 2, 5, 3, 0, 20].sort());
这里 20 出现在 3 之前,因为每个数字在比较之前都被转换为字符串,并且由于在字典中(如果有这样的字典)中“20”在“3”之前,它在结果中出现在“3”之上。
从 compareFunction 返回布尔值而不是数值
这是我在原始答案中的错误。
当您从 compareFunction 返回布尔值而不是数字时,布尔值将转换为数字。这意味着true 将变为 1,false 将变为 0,但您不会返回 -1。
var array = [
{
compareThis: 1,
originalIndex: 1
},
{
compareThis: 2,
originalIndex: 2
},
{
compareThis: -1,
originalIndex: 3
},
{
compareThis: -2,
originalIndex: 4
}
];
console.log(array.sort((a, b) => a.compareThis > b.compareThis));
这里的结果是未排序的,相同的数组,因为2和-1比较时,比较2>-1返回false,转换为0。但是当compareFunction返回0时,表示两个元素的顺序应保持不变。因此数组没有得到排序。
对这个数组进行排序的正确方法是:
var array = [
{
compareThis: 1,
originalIndex: 1
},
{
compareThis: 2,
originalIndex: 2
},
{
compareThis: -1,
originalIndex: 3
},
{
compareThis: -2,
originalIndex: 4
}
];
console.log(array.sort((a, b) => a.compareThis - b.compareThis));
因此,解决问题中提出的问题的正确方法是:
var array = [{ resVal: "25FA15", resFlow: 49, resName: "Rendimiento Tri-Seal Completo", resPhoto: "Tri-Sealseries.png", resHP: 1.5 },
{ resVal: "25FA2", resFlow: 52, resName: "Rendimiento Tri-Seal Completo", resPhoto: "Tri-Sealseries.png", resHP: 2 },
{ resVal: "45FA2", resFlow: 53, resName: "Rendimiento Hi-Cap Completo", resPhoto: "HighCapseries.png", resHP: 2 },
{ resVal: "35FA2", resFlow: 59, resName: "Rendimiento Hi-Cap Completo", resPhoto: "HighCapseries.png", resHP: 2 }];
// The requirement is to sort ascending by resHP property and then for any ties, sort descending by resFlow property.
/* array.sort(function(a, b) {
if (a.resHP > b.resHP) {
return 1;
} else if (a.resHP === b.resHP) {
if (a.resFlow > b.resFlow) {
return -1;
} else if (a.resFlow === b.resFlow) {
return 0;
} else {
return 1;
}
} else {
return -1;
}
}); */
// Simplified to the following as we are working with numbers.
array.sort(function sortByResHP(a, b) {
return (a.resHP - b.resHP) !== 0 ? (a.resHP - b.resHP) : (b.resFlow - a.resFlow);
});
console.log("Result: ", array);
当然,这可以进一步缩短,如另一个答案所示。我将保留较长版本的 compareFunction 以使其更易于阅读。
原始(错误)答案
您可以为此使用Array#sort:
array = [{ resVal: "25FA15", resFlow: 49, resName: "Rendimiento Tri-Seal Completo", resPhoto: "Tri-Sealseries.png", resHP: 1.5 },
{ resVal: "25FA2", resFlow: 52, resName: "Rendimiento Tri-Seal Completo", resPhoto: "Tri-Sealseries.png", resHP: 2 },
{ resVal: "45FA2", resFlow: 53, resName: "Rendimiento Hi-Cap Completo", resPhoto: "HighCapseries.png", resHP: 2 },
{ resVal: "35FA2", resFlow: 59, resName: "Rendimiento Hi-Cap Completo", resPhoto: "HighCapseries.png", resHP: 2 }]
array.sort(function(d1,d2) {
if(d1.resHP == d2.resHP) {
return d1.resFlow < d2.resFlow;
} else {
return d1.resHP > d2.resHP;
}
});
console.log(array);