使用`apply`更改排序功能

时间:2018-08-09 20:00:49

标签: javascript apply

我有一个排序函数,我们称它为mySort(a, b),如果a较小,它将返回1,0,-1。等于,大于b。这样,我可以执行myArray.sort(mySort)对数组进行排序。

我现在有一个视图,该数组需要按降序排序。我的第一个解决方案是只做myArray.sort(mySort).reverse()(是的,我知道这样做效率不高,但是数组包含的项少于50个)。但是我开始考虑也许可以将另一个参数添加到排序函数中,如果将其设置为falsemySort(a, b, ascending = true),它将返回相反的结果。

问题是:如果我想使用Array.sort,我需要提供一个函数。有没有一种方法可以使用apply(或call?)来创建将ascending设置为false的函数,并且该方法允许类似{{ 1}}?因为我看不到即时提供a和b的方法。

2 个答案:

答案 0 :(得分:4)

这是一个替代解决方案,但我只是将您的sort函数包装在另一个函数中。

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

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

function newSorter(ascending = true) {
   var mult = ascending ? 1 : -1;

   return function(a, b) {
       return mySort(a, b) * mult;
   } 
}

然后像这样使用它:

myArray.sort(newSorter(false));

不过请注意,我认为“比较器”是这些功能的更合适的名称。 sort听起来像是对集合进行实际排序的函数。

答案 1 :(得分:4)

您可以使用mySort.bind()来绑定上下文和初始参数,但是我认为没有类似的事情会迫使后面的参数同时保留前两个参数。

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

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

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

var heights: [CGFloat] = []
var loades: [Bool] = []

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {

      return self.heights[indexPath.row]

}



 override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "eventCell", for: indexPath) as! EventCell

        cell.date.text = ev.date

        cell.delegate = self
        cell.event = ev

        self.heights[indexPath.row] = cell.tv.frame.height

        if self.loades[indexPath.row] == false{

            self.loades[indexPath.row] = true
            tableView.reloadRows(at: [indexPath], with: .none)
        }

        return cell}