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);
}