代码之家  ›  专栏  ›  技术社区  ›  Traveling Tech Guy

使用“apply”更改排序函数

  •  3
  • Traveling Tech Guy  · 技术社区  · 6 年前

    我有一个排序函数,我们调用它 mySort(a, b) 如果a较小,则返回1,0,-1。相等,比b大。这样,我可以做一个 myArray.sort(mySort) 对我的数组进行排序。

    我现在有一个视图,数组需要按降序排序。我的第一个解决办法就是 myArray.sort(mySort).reverse() (是的,我知道它效率不高,但数组包含的项不到50个)。但是我开始想也许我可以在sort函数中添加另一个参数,如果设置为 false : mySort(a, b, ascending = true) .

    问题是:如果我想用 Array.sort 我需要提供一个函数。有没有办法 apply (或 call ?) 创建一个函数 ascending 设置为 ,在某种程度上允许 myArray.sort(myFunction.apply(null, [,,false])) ? 因为我没有办法在飞行中提供a和b。

    2 回复  |  直到 6 年前
        1
  •  4
  •   Barmar    6 年前

    你可以用 mySort.bind() 要绑定上下文和初始参数,但我不认为有任何类似的东西会强制后面的参数,而只留下前两个参数。

    可以使用添加参数的包装函数:

    myArray.sort((a, b) => mySort(a, b, true));
    

    或反转结果的符号:

    myArray.sort((a, b) => -mySort(a, b));
    

    或者交换参数顺序:

    myArray.sort((a, b) => mySort(b, a));
    

    您还可以创建一个实现此功能的高阶函数。

    function reverseArgs(func) {
        return function() {
            return func.apply(this, Array.from(arguments).reverse());
        };
    }
    
    myArray.sort(reverseArgs(mySort));
    
        2
  •  4
  •   Carcigenicate    6 年前

    这是另一种解决方案,但我将把sort函数包装到另一个函数中。

    function myRevSort(a, b) {
       return mySort(a, b) * -1;
    }
    

    或者,如果您想要一个布尔标志(虽然通常不建议这样做),您可以使用它来选择乘数,然后返回一个“sorter”函数:

    function newSorter(ascending = true) {
       var mult = ascending ? 1 : -1;
    
       return function(a, b) {
           return mySort(a, b) * mult;
       } 
    }
    

    然后像这样使用它:

    myArray.sort(newSorter(false));
    

    不过,我认为“comparator”是这些函数更合适的名称。 sort 听起来像是对集合进行排序的函数。