Reputation: 75
I have come across the array forEach
function that is a higher order function and it takes only one parameter, i.e., a closure. Now this closure internally loops through all the elements of the array one by one but does not return anything. The implementation of the closure is left to the choice of the user.
I have a custom class MyClass
that has a private variable inside it num
and a public function setNum(num: Int)
to set the value of that private variable from outside. I am just trying to create a similar function factorial
inside my custom class that takes only one parameter, i.e., a closure. However, I have to manually call the closure inside factorial
, pass the value of num
as a parameter to the closure.
Is there a way that the closure can act on num
without having passed it as a parameter? Basically I am just trying to replicate the array forEach
function. Syntax of array forEach
is:
array.forEach(body: (Int) -> Void) -> Void)
Implementation:
arr1.forEach { print($0) }
My code is as below:
import Foundation
public class MyClass {
private var factorialNumber: Double = 0
internal static var instance: MyClass?
public func setFactorialNumber(number value: Double) {
factorialNumber = value
}
public func factorial(body closure: (String?) -> Void) -> Void {
var outputString: String?
var result: Double = 1
if factorialNumber <= 0 {
outputString = nil
} else {
outputString = ""
while(factorialNumber >= 1) {
if factorialNumber == 1 {
outputString = outputString! + "\(factorialNumber) = \(result)"
break
} else {
outputString = outputString! + "\(factorialNumber) x "
}
result = result * factorialNumber
factorialNumber -= 1
}
}
// Finally closure call
closure(outputString)
}
private init() {}
public static func getInstance() -> MyClass {
if self.instance == nil {
self.instance = MyClass()
}
return self.instance!
}
}
And here is how I have to call my function to calculate the factorial:
var obj1 = MyClass.getInstance()
obj1.setFactorialNumber(number: 5)
obj1.factorial{ (result) in
print(result ?? "Factorial Result is Nil")
}
Please note that I have to pass a parameter result
inside my closure to get the result of factorial.
Upvotes: 0
Views: 2680
Reputation: 535989
Is there a way that the closure can act on num without having passed it as a parameter? Basically I am just trying to replicate the array
forEach
function ... [And, in your comment:] All I am trying to do is learn how to create higher order functions likearray.forEach
.
It's hard to understand what you think you're after, but taking you at your word, let's write forEach
. Here we go:
extension Sequence {
func myForEach(f: (Element) -> ()) {
for e in self {
f(e)
}
}
}
Let's test it:
[1,2,3].myForEach { print($0) } // prints 1, then 2, then 3
We've done it! We wrote a higher-order function that acts exactly like forEach
. So this must be how forEach
actually works, more or less.
You can see from the example that it makes no sense to ask not to have to pass a parameter into the function that our forEach
takes as a parameter. That is exactly what we must be able to do in order for that function to have an element to operate on.
Upvotes: 3