Javascript 使compare()函数更加优雅
我有以下代码:Javascript 使compare()函数更加优雅,javascript,if-statement,Javascript,If Statement,我有以下代码: function compare (a, b) { let comparison = 0; if (a.essentialsPercentage < b.essentialsPercentage) { comparison = 1; } else if (a.essentialsPercentage > b.essentialsPercentage) { comparison = -1; } else { if (a.skill
function compare (a, b) {
let comparison = 0;
if (a.essentialsPercentage < b.essentialsPercentage) {
comparison = 1;
} else if (a.essentialsPercentage > b.essentialsPercentage) {
comparison = -1;
} else {
if (a.skillsNicePercentage < b.skillsNicePercentage) {
comparison = 1;
} else if (a.skillsNicePercentage > b.skillsNicePercentage) {
comparison = -1;
} else {
if (a.startDate > b.startDate) {
comparison = 1
} else if (a.startDate < b.startDate) {
comparison = -1
}
}
}
return comparison;
}
功能比较(a、b){
让比较=0;
如果(a.基本百分比b.essentialsPercentage){
比较=-1;
}否则{
if(a.skillsNicePercentageb.SkillsInCepercentage){
比较=-1;
}否则{
如果(a.开始日期>b.开始日期){
比较=1
}否则如果(a.开始日期
最优雅的写作方式是什么?目前它似乎不太好。假设它被用作
Array.prototype.sort()
的比较函数,那么结果的符号才是重要的,它不一定非得是-1
或1
。因此,您可以简单地减去这些数字,而不是if
和else
compare(a, b) {
let comparison = b.essentialPercentage - a.essentialPercentage;
if (comparison == 0) {
comparison = b.skillsNicePercentage - a.skillsNicePercentage;
if (comparison == 0) {
comparison = a.startDate - b.startDate;
}
}
return comparison;
}
如果任何属性是字符串而不是数字,则可以使用它来代替减法。这个小函数(或等效函数)可能是js标准库中最明显的缺陷:
// returns 1 if a > b, -1 if a < b, 0 if a == b
let cmp = (a, b) => (a > b) - (a < b)
如果您愿意,您可以使用switch语句来保持每个案例的整洁有序。这将是一种“更干净”的方法,但不一定是最正确的方法。查看此线程-->
或者,您可以创建单独的函数来检查每个案例。例如,有一个函数将a.skillsNicePercentage和b.skillsNicePercentage作为参数并返回true/false。这将是清洁的,也可重复使用 根据您比较中的逻辑,这应该是可行的
function compare (a, b) {
let comparison = a.skillsNicePercentage == b.skillsNicePercentage ? (a.startDate - b.startDate) : b.skillsNicePercentage - a.skillsNicePercentage
let comparison1 = a.essentialsPercentage == b.essentialsPercentage ? b.skillsNicePercentage - a.skillsNicePercentage : comparison
return comparison1;
}
您可以在一个更简单的函数中对此进行概括,该函数接受一个字段名数组,并根据这些字段按顺序对整个数组进行排序。下面的代码从Mongoose数据库库中获得了一些灵感,允许字段名上的
-
前缀按降序排序,而不是按默认的升序排序。它也只适用于数字和字符串;如果要支持其他类型,则必须扩展代码
function multiSort(fields) {
return (a,b) => {
let result = 0;
for (let i = 0; result === 0 && i < fields.length; ++i) {
let fieldName = fields[i];
if (fieldName.charAt(0) === '-') {
fieldName = fieldName.substring(1);
if (typeof a[fieldName] === 'string') {
result = b[fieldName].localeCompare(a[fieldName]);
}
else {
result = b[fieldName] - a[fieldName];
}
} else {
if (typeof a[fieldName] === 'string') {
result = a[fieldName].localeCompare(b[fieldName]);
}
else {
result = a[fieldName] - b[fieldName];
}
}
}
return result;
};
}
试一试
函数比较新(a,b){
设c=b.essentialsPercentage-a.essentialsPercentage;
设d=b.skillsNicePercentage-a.skillsNicePercentage;
设e=a.startDate-b.startDate
返回数学符号(c | | d | | e);
}
函数比较D(a,b){
让比较=0;
如果(a.基本百分比b.essentialsPercentage){
比较=-1;
}否则{
if(a.skillsNicePercentageb.SkillsInCepercentage){
比较=-1;
}否则{
如果(a.开始日期>b.开始日期){
比较=1
}否则如果(a.开始日期 tests.map(b=>console.log(`old:${compareNew(a,b)}new:${compareOld(a,b)}`)
您可以继续使用else if
而不是在else
内部嵌套if
。除此之外,它看起来还不错。startDate
的顺序与其他两个属性相反。它在没有嵌套的情况下会一样好吗?还是故意这样(我怀疑是什么——否则你不会像你那样编写)?它在没有嵌套的情况下也会工作,可能会做不必要的测试。
function multiSort(fields) {
return (a,b) => {
let result = 0;
for (let i = 0; result === 0 && i < fields.length; ++i) {
let fieldName = fields[i];
if (fieldName.charAt(0) === '-') {
fieldName = fieldName.substring(1);
if (typeof a[fieldName] === 'string') {
result = b[fieldName].localeCompare(a[fieldName]);
}
else {
result = b[fieldName] - a[fieldName];
}
} else {
if (typeof a[fieldName] === 'string') {
result = a[fieldName].localeCompare(b[fieldName]);
}
else {
result = a[fieldName] - b[fieldName];
}
}
}
return result;
};
}
someArrayValue.sort(multisort(['essentialsPercentage', 'skillsNicePercentage', '-startDate']));
function compare(a, b) {
let c= b.essentialsPercentage - a.essentialsPercentage;
let d= b.skillsNicePercentage - a.skillsNicePercentage;
let e= a.startDate - b.startDate
return Math.sign(c||d||e);
}