Swift - 通过多次比较对数组进行排序

Swift - Sort Array with several comparison

我的问题很简单:

如果用户完成锻炼,他将输入他的时间,如果没有,他将输入次数或重复次数。

为了简单起见,结果对象是这样的:

Result
 |_ resultValue (Int) // It can be time in seconds or number of reps
 |_ isFinished (Int) // It can be 0 (not finished) or 1 (finished)

我想像这样对结果数组进行排序:

  1. First: All results with isFinished == 1 are higher than the others
  2. Then: Sort results where isFinished == 1 by resultValue DESC
  3. Finally: Sort results where isFinished == 0 by resultValue ASC

我试过类似的东西:

self.results = self.results.sorted {
 ([=12=].result.isForTimeFinished!, [=12=].result.resultValue!) > 
 (.result.isForTimeFinished!, .result.resultValue!)
}

所以未完成锻炼的结果是锻炼完成后的结果,但是 "Sort results where isFinished == 1 by resultValue DESC" 不行...

你知道我如何将所有这些结合起来吗?

我个人会在你的结果模型中添加一个计算的 var,称为 searchScore 之类的东西,它会被计算(虽然我没有完全遵循你的目标,但它看起来基本上将您的数据分成 3 层,然后使用 ascending/descending),然后您可以对其进行简单排序。

所以像这样

class Result {
...
    var searchScore: Double {
       return *ALGORITHM FOR SCORE*
    }
}
let sorted = results.sorted {[=10=].searchScore < [=10=].searchScore}

这种方法的真正优点是让您的代码更简洁,而不必在错误的地方排序的问题变得非常复杂。

试试这个:

self.results = self.results.sorted {
    if [=10=].result.isForTimeFinished != .result.isForTimeFinished {
        return [=10=].result.isForTimeFinished > .result.isForTimeFinished
    }
    else if [=10=].result.isForTimeFinished == 0 {
        return [=10=].result.resultValue > .result.resultValue
    }
    else {
        return [=10=].result.resultValue < .result.resultValue
    }
}

注意:我可能把标志弄反了,但还是玩了一下

逻辑 OR 首先停止 TRUE 计算,因此不需要计算下一个表达式。当 [=13=] 应该在列表中的 </code> 之上时有 3 条规则,尝试下一个:</p> <pre><code>self.results = self.results.sorted { let b0 = [=10=].result.isForTimeFinished! let b1 = .result.isForTimeFinished! let v0 = [=10=].result.resultValue! let v1 = .result.resultValue! // [=10=] will be above in the list if returning true, otherwise it will be listed lower return b0 && !b1 // is finished > not finished || b0 && b0 == b1 && v0 < v1 // both finished, higher value || !b0 && b0 == b1 && v0 > v1 // both not finished, lower value }