用高阶函数重构给定的 for-in 循环

Posted

技术标签:

【中文标题】用高阶函数重构给定的 for-in 循环【英文标题】:Refactoring the given for-in loop with a higher order function 【发布时间】:2018-06-14 03:26:55 【问题描述】:

给定以下代码:

let assetsFetchResult = PHAsset.fetchAssets(in: panoramasCollection, options: fetchOptions)
private var pAssets = [PHAsset]()
for i in 0..<assetsFetchResult.count 
    let asset = assetsFetchResult.object(at: i)
    pAssets.append(asset)

如何使用mapfilterreduce 等高阶函数重构for-in 循环?如您所见,我依赖于索引变量,并且各种高阶函数似乎没有在它们各自的闭包中给我索引。

【问题讨论】:

swift 中的高阶函数:-map、filter、reduce 等......似乎知道像“迭代”这样的函数,它会给我闭包中的索引和值。我必须自己创建吗? 您是否在问如何在不使用for i in 循环的情况下填充pAssets 数组? @rmaddy yesss!!! 【参考方案1】:

mapfilter 等“高阶函数”不适用于 PHFetchResultassetsFetchResult 就是这样。

你可以这样做:

private var pAssets = [PHAsset]()
assetsFetchResult.enumerateObjects  (asset, index, stop) in
    pAssets.append(asset)

【讨论】:

没有。你不能说for asset in assetsFetchResult。这就是问题所在。 @matt 哎呀。我被文档指出PHFetchResult 符合NSFastEnumeration 的事实吓坏了。我删除了那部分答案。 是的,过去可以通过利用其 NSFastEnumeration 一致性使 PHFetchResult 符合 Sequence。但这已经不可能了。正如我所说,我认为这是一个错误。【参考方案2】:

不幸的是,PHFetchResult 不能像 Swift 序列一样被枚举(即使用for...in)。过去可以通过巧妙的花招来做到这一点,但后来他们将 PHFetchResult 变成了泛型并毁了它。

这更令人沮丧,因为在 Objective-C 中您可以使用for...in 枚举它。

在 Swift 中,您只需使用为此目的提供的 Cocoa 方法(或使用索引)。

【讨论】:

如果方便的话,我有一个关于这个问题的错误:bugs.swift.org/browse/SR-1576【参考方案3】:

是的,你可以做到!但是您需要范围,因为 PHFetchResult 不是集合。

let assetsFetchResult = PHAsset.fetchAssets(in: panoramasCollection, options: fetchOptions)
private var pAssets = (0..<assetsFetchResult.count).map(assetsFetchResult.object(at:))

【讨论】:

以上是关于用高阶函数重构给定的 for-in 循环的主要内容,如果未能解决你的问题,请参考以下文章

Python--高阶函数函数嵌套名称空间及变量作用域闭包装饰器

Java精练代码:一次Java函数式编程的重构之旅

由重构react组件引发的函数式编程的思考

由重构react组件引发的函数式编程的思考

JavaScript高阶函数

Swift高阶函数-MapFilterReduce