Javascript排序自定义比较器函数 - 对排序数组进行排序

fen*_*yer 25 javascript arrays sorting

我有一个以下形式的对象数组:

arr[0] = { 'item1' : 1234, 'item2' : 'a string' };
Run Code Online (Sandbox Code Playgroud)

我先把'item1'它排序,直截了当.现在我想再次排序arr(按排序'item1'),但这次'item2'只是对于'item1'相同的元素.最终的数组看起来像:

arr = [
  { 'item1' : 1234, 'item2' : 'apple' },
  { 'item1' : 1234, 'item2' : 'banana' },
  { 'item1' : 1234, 'item2' : 'custard' },
  { 'item1' : 2156, 'item2' : 'melon' },
  { 'item1' : 4345, 'item2' : 'asparagus' } 
];
Run Code Online (Sandbox Code Playgroud)

我试着为第二种情况写一个排序函数,如下所示:

arr.sort(function(a,b){
  if(a.item1 === b.item1){
    return a.item2 > b.item2 ? 1 : a.item2 < b.item2 : -1 : 0;
  }
});
Run Code Online (Sandbox Code Playgroud)

我可以在一个函数中组合两种类型以获得最终排序的数组,但是在某些情况下我将只需要'item1'或只是排序'item2'.

Pet*_*nov 33

您可以有四种不同的比较函数 - 一种按item1排序,一种按item2排序,一种按item1排序然后按item2排序,另一种按item2排序,然后按item1排序.

例如:

arr.sort(function(a,b){
  if(a.item1 == b.item1){
    return a.item2 > b.item2 ? 1 : a.item2 < b.item2 ? -1 : 0;
  }

  return a.item1 > b.item1 ? 1 : -1;
});
Run Code Online (Sandbox Code Playgroud)

  • 太好了,人们可以在 javascript 中的排序函数中简单地使用比较器。 (2认同)

小智 7

我最近遇到了同样的问题。提供了与 langpavel 类似的解决方案,但我更喜欢将其一分为二。首先是一个链式比较器助手,它将允许多个排序规则,每个排序规则在相等的情况下作为决胜局应用:

    type Comparator<T> = (a: T, b: T) => number; // -1 | 0 | 1

    /**
     * Allow to chain multiple comparators, each one called to break equality from the previous one.
     */
    function chainedComparator<T>(...comparators: Comparator<T>[]): Comparator<T> {
        return (a: T, b: T) => {
            let order = 0;
            let i = 0;
    
            while (!order && comparators[i]) {
                order = comparators[i++](a, b);
            }
    
            return order;
        };
    }
Run Code Online (Sandbox Code Playgroud)

我喜欢它,因为它需要并返回排序比较器。因此,如果您有其他比较器的集合,则它们很容易使用。

然后你可以通过一个额外的助手来简化你的生活。这个基于每个项目上传递的 lambda 的结果返回一个排序比较器。

    type Comparable = string | number;

    /**
     * Returns a comparator which use an evaluationFunc on each item for comparison
     */
    function lambdaComparator<T>(evaluationFunc: ((item: T) => Comparable), reversed = false): Comparator<T> {
        return (a: T, b: T) => {
            const valA = evaluationFunc(a);
            const valB = evaluationFunc(b);
            let order = 0;
    
            if (valA < valB) {
                order = -1;
            } else if (valA > valB) {
                order = 1;
            }
            return reversed ? -order : order;
        };
    }
Run Code Online (Sandbox Code Playgroud)

reversed 这里不需要回答问题,但可以轻松颠倒顺序。

要具体回答这个问题,请使用我们的两个比较器:

    arr.sort(chainedComparator(
        lambdaComparator(a => a.item1),
        lambdaComparator(a => a.item2.toLowerCase()) // "banana" before "Melon"
    ));
Run Code Online (Sandbox Code Playgroud)

因为最初的问题是在纯 JavaScript 中,精度:如果您不习惯 TypeScript,您可以通过删除键入<T>, : T,: ((item: T) => Comparable)无处不在的两type行并取出来获得普通的 JavaScript 。