每次调用的结果均调用n次

您可以在我的博客上阅读此帖子–>>> 此处

今天,我在Sash Zats的一条推文中遇到了这个问题:一个函数如何调用n次,并使用每个调用的参数作为上次调用的结果?

当然,假设我们要调用一个函数5次,则可以这样做:

///Adds 5 to a number 
func addFive(to number: Int) -> Int {
return number + 5
}

let result = addFive(to: addFive(to: addFive(to: addFive(to: addFive(to: 2)))))
print(result) //27

但这就是我们真正想要写的吗?

救援标准图书馆

我做了一些研究,然后发现了Chris Eidhof的回应,其中提到了一种叫做UnfoldSequence的类型。

事实证明,标准库具有一个名为sequence(first:next:)的函数,可以执行此操作。 从文档中:

返回由nextfirst重复懒惰应用形成的序列。

为了完整起见,下面是整个函数签名:

 /// - Parameter first: The first element to be returned from the sequence. 
/// - Parameter next: A closure that accepts the previous sequence element and
/// returns the next element.
/// - Returns: A sequence that starts with `first` and continues with every
/// value returned by passing the previous element to `next`.
public func sequence(first: T, next: @escaping (T) -> T?) -> UnfoldFirstSequence

但是我们需要更多的权利吗? 我们需要控制该函数需要被调用的次数。 我们不想将大量的next()调用混为一谈。

因此,我进一步走了一步,编写了这个小功能,它可以满足我们的需求:

 /// Calls a function n times passing the result of each call into the next call. 
func call(_ function: @escaping (T) -> T?, initialInput: T, repetitions: Int) -> T? {
var seq = sequence(first: initialInput, next: function)

var result: T?

//Doing it once more avoids seq.next()
for _ in 0..<(repetitions + 1) {
result = seq.next()
}

return result
}

请注意,我们将next()调用n + 1次,因为否则第一次调用将导致初始输入成为输出。

包起来

我们已经看到很少的工作和标准库的一些帮助可以使我们的生活更轻松。 让我们看看最终结果!

 //Before 
let manualResult = addFive(to: addFive(to: addFive(to: addFive(to: addFive(to: 2)))))

//After
let functionResult = call(addFive(to:), initialInput: 2, repetitions: 5)

您可以在此要点中找到完整的代码。

希望对您有所帮助! 🙂