Swift:Program for Addition of 2 Numbers Using Closure

Swift closure adding more than 2 value

Compiler does not reproduce type of result correctly in this case. You should help it a little:

var calculate: (Int,Int,Int) -> Int
calculate = { Int($0+$1+$2) }
print(calculate(5,8,90)) // "103\n"

How to use trailing closure in if condition?

You have to put parentheses around the function call:

if "SMITH" == (lastNameForPerson(Person()) {$0.uppercaseString}) {
print("It's bob")
}

Or you put them around the == comparison (around the if condition) in a C-style manner:

if ("SMITH" == lastNameForPerson(Person()) {$0.uppercaseString}) {
print("It's bob")
}

Alternatively, you can move the closure inside the parameter list (though this requires you to explicitly name the parameter):

if "SMITH" == lastNameForPerson(Person(), caseFolding: {$0.uppercaseString}) {
print("It's bob")
}

The reason this problem arises is that the if statement 'claims' the {} block, i.e. it doesn't belong to the lastNameForPerson call any more. For the compiler, the second code block now looks like a normal block that wasn't properly separated from the previous (if) statement.


You should probably consider avoiding a construct like this in general, since it might be hard to read (at first). Instead, you could store the result of the function call in a variable and compare that instead:

let lastName = lastNameForPerson(Person()) {$0.uppercaseString}
if "SMITH" == lastName {
print("It's bob")
}

How to use Closure to recycle code in Swift?

To expand on the already existing answers, functions allow you a high degree of reusability, and for your particular example, high-order functions might work.

Let's begin with defining the basic blocks for the data comparison operations you want to do:

/// Creates a function that acts as a comparator against the received value
func isGreater<T: Comparable>(than value: T) -> (T) -> Bool {
return { $0 > value }
}

/// Creates a function that checks if the argument in betwen the two bounds
func isWithin<T: Comparable>(_ lower: T, and upper: T) -> (T) -> Bool {
return { lower..<upper ~= $0 }
}

/// Creates a function that checks if an array contains elements that satisfy the given predicate
func contains<T>(_ predicate: @escaping (T) -> Bool) -> ([T]) -> Bool {
return { $0.contains(where: predicate) }
}

Both of the above functions create as and return a new function that can be stored and reused anywhere in your app.

Now, let's put the functions to good use:

func hasAboveThreshold(threshold: Double) -> ([Double]) -> Bool {
return contains(isGreater(than: threshold))
}

func hasBetweenThreshold(threshold1: Double, threshold2: Double) -> ([Double]) -> Bool {
return contains(isWithin(threshold1, and: threshold2))
}

Note how every piece (function) from the first code snippet was reused via function composition. Thus, you achieve the reusability goal.

Usage example:

let numbers = [1.1, 2.2, 3.3, 4.4, 5.5]
let hasBetween1AndTen = hasBetweenThreshold(threshold1: 1.0, threshold2: 10.0)
print(hasBetween1AndTen(numbers))

As you store the hasBetween1AndTen into a variable, you can reuse it an any time, and in any place that has access to that variable.

How to receive an output for a method from a closure in Swift?

You should use a completionHandler concept to achieve async operations like this:

struct TweetFetcher {
let tweetCount = 100
let swifter = Swifter(consumerKey: key, consumerSecret: secret)

func fetchTweets(with searchText: String, completion: @escaping ([TweetSentimentClassifierInput]?, Error?) -> Void) {

swifter.searchTweet(using: searchText, lang: "en", count: tweetCount, tweetMode: .extended) {(results, searchMetadata) in
var tweets = [TweetSentimentClassifierInput]()
let data = results.description.data(using: .utf8)

do {
let decodedData = try JSONDecoder().decode([TweetData].self, from: data!)
} catch {
print("Error with decoding, \(error)")
completion(nil, error)
}

for tweet in decodedData {
let tweetForClassification = TweetSentimentClassifierInput(text: tweet.full_text)
tweets.append(tweetForClassification)
}
completion(tweets, nil)
} failure: { (error) in
print("Error with the Twitter API request, \(error)")
completion(nil, error)
}
}
}

Usage

let fetcher = TweetFetcher()
fetcher.fetchTweets(with: "Keyword...") { tweets, error in
if let error = error {
print(error.localizedDescription)
} else {
// Use tweets array content here ...
}
}

swift maximum consecutive positive numbers

Update: Simpler solution: Split the array into slices of
positive elements, and determine the maximal slice length:

let  numbers = [1,3,4,-1,-2,5,2,-2,-3,-4,5]
let maxConsecutive = numbers.split(whereSeparator: { $0 <= 0 }).map { $0.count }.max()!
print(maxConsecutive) // 3

Old answer:) Using the ideas from Swift running sum:

let  numbers = [1,3,4,-1,-2,5,2,-2,-3,-4,5]

let maxConsecutive = numbers.map({
() -> (Int) -> Int in var c = 0; return { c = $0 > 0 ? c + 1 : 0; return c }
}()).max()!

Here map() maps each array element to the count of consecutive positive
numbers up to the elements position, in this case

[1, 2, 3, 0, 0, 1, 2, 0, 0, 0, 1]

The transformation is created as an "immediately evaluated
closure" to capture a variable c which holds the current number of
consecutive positive numbers. The transformation increments or resets c,
and returns the updated value.

If the array is possibly large then change it to

let maxConsecutive = numbers.lazy.map( ... ).max()!

so that the maximum run length is determined without creating an
intermediate array.

Calling a swift function right after the closing bracket?

There are three types of closures in Swift:

  • Global functions are closures that have a name and do not capture any values.
  • Nested functions are closures that have a name and can capture values from their enclosing function.
  • Closure expressions are unnamed closures written in a lightweight syntax that can capture values from their surrounding context.

...

Closure expressions are a way to write inline closures in a brief,
focused syntax.

(Source: Closures in the Swift book.)

In your first example:

var test = { () -> String in return "this works" }()

{ ... } is a closure expression. This expression is evaluated
with an empty argument list (). The result is the string
"this works" which is then assigned to the variable.

Your second example is a global function.
Global functions are (named) closures, but not closure expressions.
There is (as far as I know) no similar way to define a function which
is immediately evaluated.



Related Topics



Leave a reply



Submit