Javascript - 按多个条件对数组进行排序

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28560801/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 09:11:00  来源:igfitidea点击:

Javascript - sorting array by multiple criteria

javascriptarrayssorting

提问by user2866434

I have an array of objects:

我有一个对象数组:

var arr = [
  {title:'50 - 50'},
  {title:'100 - 100'},
  {title:'50 - 65'},
  {title:'100 - 125'}
];

I'm attempting to sort this array so that the items appear in the following order:

我正在尝试对此数组进行排序,以便项目按以下顺序显示:

var arr = [
  {title:'50 - 50'},
  {title:'50 - 65'},
  {title:'100 - 100'},
  {title:'100 - 125'}
];

Currently I'm using the following sorting function to attempt this:

目前我正在使用以下排序功能来尝试:

arr.sort(function(a, b){
  var titleA = a.title;
  var titleB = b.title;
  var arrA = titleA.split(' - ');
  var arrB = titleB.split(' - ');
  var keyA = parseInt(arrA[0]), 
      keyB = parseInt(arrB[0]);

  // Compare the 2 keys
  if(keyA < keyB) return -1;
  if(keyA > keyB) return 1;
  return 0;
});

However, this returns the items in the following order:

但是,这会按以下顺序返回项目:

var arr = [
  {title:'50 - 65'},
  {title:'50 - 50'},
  {title:'100 - 125'},
  {title:'100 - 100'}
];

It looks like I need to sort by the first number in the title and then the second number. Any ideas?

看起来我需要先按标题中的第一个数字排序,然后再按第二个数字排序。有任何想法吗?

回答by meskobalazs

In pseudocode, the logic would be the following:

在伪代码中,逻辑如下:

Procedure: comparator(a,b)

程序:比较器(a,b)

  1. If a < bthen return -1
  2. If a = bthen call comparator(a1, b1)recursively, where a1and b1are the comparable values of the next level in the sorting.
  3. If a > bthen return 1
  1. 如果a < b那么return -1
  2. 如果a = b然后comparator(a1, b1)递归调用,其中a1b1是排序中下一个级别的可比较值。
  3. 如果a > b那么return 1


In your concrete case, you can do simply do it by modifying your code a bit:

在您的具体情况下,您可以通过稍微修改代码来简单地做到这一点:

if (keyA < keyB) {
    return -1;
} else if (keyA > keyB) {
    return 1;
} else { // keyA == keyB
    if (titleA < titleB) {
        return -1;
    } else if (title > titleB) {
        return 1;
    } else {
        return 0;
    }
}

回答by Alex Kopachov

Try this:

试试这个:

arr.sort(function(a, b){
  var titleA = a.title;
  var titleB = b.title;
  var arrA = titleA.split(' - ');
  var arrB = titleB.split(' - ');
  var keyA1 = parseInt(arrA[0]), keyA2 = parseInt(arrA[1]) 
      keyB1 = parseInt(arrB[0]), keyB2 = parseInt(arrB[1]);

  // Compare the 2 keys
  if (keyA1 < keyB1) return -1;
  if (keyA1 > keyB1) return 1;
  if (keyA2 < keyB2) return -1;
  if (keyA2 > keyB2) return 1;
  return 0;
});

回答by Leonid Pyrlia

Here is a cleaner and shorter version that does not require a bunch of nested if/else cases:

这是一个更简洁、更短的版本,不需要一堆嵌套的 if/else 案例:

const sorted = arr.sort((a,b) => {

    const [a1, a2] = a.title.split(' - ').map(Number);
    const [b1, b2] = b.title.split(' - ').map(Number);

    return a1 - b1 || a2 - b2;

});

回答by Mukesh Agarwal

Create a compare function similar to this:

创建一个类似这样的比较函数:

arr.sort(function(a, b){
  var titleA = a.title;
  var titleB = b.title;
  var arrA = titleA.split(' - ');
  var arrB = titleB.split(' - ');
  var keyA1 = parseInt(arrA[0]), 
      keyA2 = parseInt(arrA[1]),
      keyB1 = parseInt(arrB[0]),
      keyB2 = parseInt(arrB[1]),

  // Compare the 2 keys
  if(keyA1 < keyB1) return -1;
  if(keyA1 > keyB1) return 1;
  else
  {
      if(keyA2 < keyB2) return -1;
      if(keyA2 > keyB2) return 1;
      return 0;
});

回答by Evan Siroky

Another possibility is to compose a sort function based off of multiple comparator functions. Here is an example function that would do this:

另一种可能性是基于多个比较器函数组合一个排序函数。这是一个可以执行此操作的示例函数:

function makeMultiCriteriaSort (...criteria) {
  return (a, b) => {
    for (let i = 0; i < criteria.length; i++) {
      const curCriteriaComparatorValue = criteria[i](a, b)
      // if the comparison objects are not equivalent, return the value obtained
      // in this current criteria comparison
      if (curCriteriaComparatorValue !== 0) {
        return curCriteriaComparatorValue
      }
    }
    return 0
  }
}

// sort an array with multiple criteria
arr.sort(makeMultiCriteriaSort(comparator1, comparator2))

The npm package thenbytakes this idea to the next level.

npm 包thenby将这个想法提升到了一个新的水平。