Sort(by:) 方法 / 需要解释

Sort(by:) method / Need explanation

提问人:neuraldag 提问时间:10/3/2023 更新时间:10/3/2023 访问量:54

问:

在我的学习书中遇到了这个新的“sort(by:)”方法,但没有对它的工作原理和原因进行任何合理的解释,下面是一个代码示例:

var numbers = [1, 2, 5, 3, 7, 4, 6, 9, 8]

let sortClosure = { (a: Int, b: Int) -> Bool in
    return a < b
}

numbers.sort(by: sortClosure)
print(numbers)

根据我自己的研究,我发现如果 a(数组的第一个元素)需要在 b(数组的第二个元素)之前,则闭包返回 true 并以这种方式对数组进行排序。

但是我的编译器说,我不明白为什么,因为 2 怎么可能小于 1?return a < b == falsereturn a > b == true

请帮助我了解我的编译器出了什么问题,或者我无法理解它从该方法中工作的问题?sort(by:)

Swift 排序 方法 闭包

评论

1赞 Joakim Danielson 10/3/2023
你是怎么得出编译器认为 2 小于 1 的结论的?在闭包中添加以下代码行,并亲眼看看会发生什么,print(a, b, a < b)
0赞 neuraldag 10/3/2023
是的,现在我明白了。但是为什么需要 2 作为 a 和 1 作为 b?我以为 a 是数组的第一个元素@JoakimDanielson
1赞 Joakim Danielson 10/3/2023
这就是底层排序算法遍历数组的原因。我不是专家,但如果您想开始更深入地研究排序算法,请参阅例如这个问题
1赞 Larme 10/3/2023
不要关心方法背后的排序算法。它可以是气泡排序,也可以是任何其他类型(见 en.wikipedia.org/wiki/Sorting_algorithm)。只需关注“我有两个元素,即闭包参数,比较它们”,仅此而已。sort()
0赞 neuraldag 10/3/2023
谢谢你们,我想我明白了将来如何使用它。我现在不想更深入地研究排序算法,因为我是新手。因此@Larme我将使用:)方法

答:

1赞 Larme 10/3/2023 #1

有各种排序算法:冒泡排序、快速排序、合并排序等。 它们各有利弊,主要是关于:内存使用、复杂性等。
简而言之:排序时它会在内存中创建另一个或更多完整数组吗?如果阵列很大,会不会需要很多时间?等。

另一个 StackOverflow 问题中,您可能会看到似乎使用了哪种算法,并且该算法似乎在过去发生了变化。 明天,算法可能会改变甚至适应(例如:如果少于 1k 个元素,请对逻辑 1 进行排序,但如果有更多元素,请对逻辑 2 进行排序,因为它在内存上更便宜,而且您目前没有很多 RAM,等等)

但是,由于你想使用高级方法,而不是实现自己的算法,所以不要专注于它。sort(by:)

只需专注于在闭包中要做什么,这很简单:

  • 参数中有 2 个元素
  • 从中检索要比较的信息:无论是原始值、计算属性、您想要的另一个相关值等。
  • 比较这两个值:如果希望将第一个参数放在第二个参数之前,则返回 true,在另一种情况下返回 false。

如果需要,可以打印该值:

let returnValue = a < b
print("Comparing \(a) vs \(b) and returning: \(returnValue)")
return returnValue

在您的简单情况下,您正在比较原始值,即 .Int

所以前面解释的全行是:

let valueFromAToCompare = a
let valueFromBToCompare = b
return valueFromAToCompare < valueFromBToCompare

这显然可以简化为 .return a < b

如果我们的数组中有这样的结构,并且您想根据其编号进行排序:

struct MyStruct {
    let number: Int
    let subNumber: String
}

关闭将是:

let valueFromAToCompare = a.number
let valueFromBToCompare = b.number
return valueFromAToCompare < valueFromBToCompare

可以简化为:.return a.number < b.number

但正如你所猜到的,以后可能会有更复杂的排序逻辑:比较数字,但如果 s 相等,那么比较 ,因此闭包可以让你把你的整个逻辑:numbersubNumber

if a.number == b.number {
    return a.subNumber < b.subNumber
} else {
    return a.number < b.number
}

当然,它可以简化或以不同的方式编写,但这是为了让示例更易于理解。