Swift中如何用指定闭包查找Int数组最值?解析代码逻辑
解析基于闭包的数组最值查找逻辑
先明确task函数的核心逻辑
这个函数的作用是遍历数组,根据传入的闭包规则,动态维护一个候选值a,最终返回符合规则的元素:
- 初始时
a为nil(对应还未开始遍历的状态) - 遍历数组的每个元素
i,调用闭包判断(i, a)是否满足规则 - 如果闭包返回
true,就把当前元素i设为新的候选值a - 遍历结束后返回最终的候选值
a
闭包参数的含义
闭包的两个参数$0和$1是固定对应函数传入的参数:
$0:当前遍历到的数组元素(即循环中的i)$1:当前的候选值a(可选类型,因为初始状态是nil)
最值查找的逻辑拆解
查找最值的本质是逐个比较,保留符合“更大/更小”规则的元素,所以需要拿当前元素和之前的候选值对比——这就是为什么需要两个参数的原因:一个代表“当前待检查的元素”,一个代表“之前筛选出的最优候选”。
关于你提供的闭包的问题
你给出的闭包其实写反了,导致无法正确得到最值,先解析逻辑,再给出正确写法:
错误的最大值闭包(你提供的)
let max = task(array: numbers) { $1 == nil || $1! > $0 }
$1 == nil:处理第一个元素,此时候选值为空,直接选中第一个元素(返回true,a被设为第一个元素)$1! > $0:判断当前候选值是否大于当前元素,如果是则替换候选值为当前元素。这会导致最终保留的是数组中的最小值,因为每次遇到比候选值小的元素都会替换。
正确的最大值闭包
要找最大值,应该在当前元素比候选值大的时候替换候选值,所以闭包应该写为:
let max = task(array: numbers) { $1 == nil || $0 > $1! }
逻辑:
- 第一个元素直接选中
- 后续元素如果比当前候选值大,就替换候选值,最终得到数组最大值
错误的最小值闭包(你提供的)
let min = task(array: numbers) { $1 == nil || $1! < $0 }
$1! < $0:判断当前候选值是否小于当前元素,如果是则替换,最终会保留数组中的最大值。
正确的最小值闭包
要找最小值,应该在当前元素比候选值小的时候替换候选值:
let min = task(array: numbers) { $1 == nil || $0 < $1! }
逻辑:
- 第一个元素直接选中
- 后续元素如果比当前候选值小,就替换候选值,最终得到数组最小值
总结
- 两个参数的作用是:用当前遍历元素和历史候选值做对比,实现逐步筛选的逻辑
- 闭包的核心是定义“什么时候需要更新候选值”,对应最值查找就是“当前元素比候选值更大/更小”的时候更新
内容的提问来源于stack exchange,提问作者daria
相关产品推荐
相关产品推荐

