Executing a closure in place of the condition of an if statement - swift

The following works. It prints: At least one true
let arr = [false, false, false, true, false, false, true, false]
// Variable set by executing a closure...
let hasAtLeastOneTrue: Bool = {
var x = false
arr.forEach {
x = x || $0
}
return x
}()
if hasAtLeastOneTrue {
print("At least one true")
} else {
print("All false")
}
Is it possible to compress the code by eliminating the constant hasAtLeastOneTrue and replace the conditional with the closure? Something like:
if {CLOSURE CODE}() {
print("At least one true")
} else {
print("All false")
}

Yes. The key is to wrap the entire closure invocation with brackets:
if ({
var x = false
arr.forEach {
x = x || $0
}
return x
}()) {
print("At least one true")
} else {
print("All false")
}
Though I think this is a lot less readable than if hasAtLeastOneTrue { .... I suggest that you still name your closures, or just use inner functions.
Note that in this case, you can just do:
if arr.contains(true) {
print("At least one true")
} else {
print("All false")
}

Related

How to make the closures shorter?

How to make the closures shorter? I want to know the simple programming of the closures.
let closures = { (fillBefore: Bool, fillAfter: Bool) -> String in
if fillBefore && fillAfter {
return kCAFillModeBoth
} else if !fillBefore && fillAfter {
return kCAFillModeBackwards
} else if fillBefore && !fillAfter {
return kCAFillModeForwards
} else {
return kCAFillModeRemoved
}
}
anim?.fillMode = closures((item?.fillBefore)!, (item?.fillAfter)!)
How to make the closures shorter?
Based on your case, I think that at some point you have to evaluate both of booleans, so I would assume that there is no "shorter" code for handling it.
However, you might be looking for a "neater" approach, so I would suggest to evaluate them as pair of booleans (tuple), with a switch statement:
let closure = { (fillBefore: Bool, fillAfter: Bool) -> String in
switch (fillBefore, fillAfter) {
case (true, true):
return kCAFillModeBoth
case (false, true):
return kCAFillModeBackwards
case (true, false):
return kCAFillModeForwards
default: // on your case, it would be the same as (false, false)
return kCAFillModeRemoved
}
}
let myClosure = closure(false,false)
myClosure // removed

Swift 3 - Atomic boolean

Does anybody know how to make an atomic boolean in iOS 10?
Current code:
import UIKit
struct AtomicBoolean {
fileprivate var val: UInt8 = 0
/// Sets the value, and returns the previous value.
/// The test/set is an atomic operation.
mutating func testAndSet(_ value: Bool) -> Bool {
if value {
return OSAtomicTestAndSet(0, &val)
} else {
return OSAtomicTestAndClear(0, &val)
}
}
/// Returns the current value of the boolean.
/// The value may change before this method returns.
func test() -> Bool {
return val != 0
}
}
The code works as expected, but i keep getting the warning:
'OSAtomicTestAndSet' was deprecated in iOS 10.0: Use atomic_fetch_or_explicit(memory_order_relaxed) from <stdatomic.h> instead
I can't get it to work with atomic_fetch_or_explicit(memory_order_relaxed).
Does anyone know how to convert my current code to iOS 10, in order to get rid of this warning?
Thank you!
the better way is to avoid it ... If you would like to mimick it just to synchronise access to your AtomicBoolean, use synchronisation avaiable in GCD
for example
import PlaygroundSupport
import Foundation
import Dispatch
PlaygroundPage.current.needsIndefiniteExecution = true
let q = DispatchQueue(label: "print")
struct AtomicBoolean {
private var semaphore = DispatchSemaphore(value: 1)
private var b: Bool = false
var val: Bool {
get {
q.async {
print("try get")
}
semaphore.wait()
let tmp = b
q.async {
print("got", tmp)
}
semaphore.signal()
return tmp
}
set {
q.async {
print("try set", newValue)
}
semaphore.wait()
b = newValue
q.async {
print("did", newValue)
}
semaphore.signal()
}
}
}
var b = AtomicBoolean()
DispatchQueue.concurrentPerform(iterations: 10) { (i) in
if (i % 4 == 0) {
_ = b.val
}
b.val = (i % 3 == 0)
}
prints
try get
try set false
try set false
try set true
did false
got false
try get
try set true
did false
try set false
did true
did true
try set true
try set false
got false
try set false
did false
try get
did true
try set true
did false
did false
got false
try set false
did true
did false
Apple confirmed that read and write of Bool value is not an atomic operation in Swift.
But there are many ways to synchronize.
Example
Somewhere add below global-function logic:
func synchronized<T>(_ lock: AnyObject, _ body: () throws -> T) rethrows -> T {
objc_sync_enter(lock)
defer { objc_sync_exit(lock) }
return try body()
}
And use like:
let myLock = NSObject();
// ...
synchronized(myLock) {
// Something not thread safe here...
}
Your first option is to...
just use a regular lock and guard your value access, the other is...
to use Swift Atomics
Then you can just say
var value = ManagedAtomic<UInt8>(0)
// Atomic store
value.store(2, ordering: .relaxed)
// Atomic load
value.load(ordering: .relaxed)

Where does this line of code return to?

In the code below, I'm confused as to where the return statement in the code returns to? When executed, it works as expected, but does it return to:
if userIsInTheMiddleOfTyping == true
or does it return to:
if let digit = sender.currentTitle
Below is the full chunk of code where this applies.
class ViewController: UIViewController {
private var userIsInTheMiddleOfTyping = false
private var decimalUsed = false
#IBAction private func touchDigit(sender: UIButton)
{
if let digit = sender.currentTitle {
if userIsInTheMiddleOfTyping == true {
if digit == "." && decimalUsed == true {
return //where does this return to?
} else if digit == "." && decimalUsed == false {
decimalUsed = true
}
let textCurrentlyInDisplay = display.text!
display.text = textCurrentlyInDisplay + digit
} else {
display.text = digit
}
userIsInTheMiddleOfTyping = true
}
}
A return always returns out of the function, so in this case it returns to the line of code that calls touchDigit(...)
Basically here, the return just stops the execution of the touchDigit function.
(Which means that none of the code following the return will be run)
The return simply stops the code. You can put it in functions if you would like. For example:
If I want to continue running some code only if a certain statement is true, then you can return the function to stop it if it is false.
func something(a: Int, b: Int) {
if a != b {
return//Stops the code
}
//Some more code -- if a is not equal to b, this will not be called
}
Remember, this only works with void functions. It can work with others as well, but that is slightly different. You must return something along with it. Another example:
func somethingElse(a: Int, b: Int) -> Bool{
if a != b {
return false //stops the code, but also returns a value
}
return true //Will only get called if a == b
}
In this function, it is return a Boolean. If a != b, then return false is written because that returns false while also stoping the code.
For more on returns, you can visit Apple's documentation on functions.

How to check for palindrome in Swift using recursive definition

I like many of the features in Swift, but using manipulating strings are still a big pain in the ass.
func checkPalindrome(word: String) -> Bool {
print(word)
if word == "" {
return true
} else {
if word.characters.first == word.characters.last {
return checkPalindrome(word.substringWithRange(word.startIndex.successor() ..< word.endIndex.predecessor()))
} else {
return false
}
}
}
This code fails miserably whenever the string's length is an odd number. Of course I could make it so the first line of the block would be if word.characters.count < 2, but is there a way in Swift to get substrings and check easily?
Update
I like many of the suggestions, but I guess the original question could be misleading a little, since it's a question about String more than getting the right results for the function.
For instance, in Python, checkPalindrome(word[1:-1]) would work fine for the recursive definition, whereas Swift code is much less graceful since it needs other bells and whistles.
return word == String(word.reversed())
func isPalindrome(myString:String) -> Bool {
let reverseString = String(myString.characters.reversed())
if(myString != "" && myString == reverseString) {
return true
} else {
return false
}
}
print(isPalindrome("madam"))
I have used the below extension to find whether the number is Palindrome or Not.
extension String {
var isPalindrome: Bool {
return self == String(self.reversed())
}
}
Sometimes having a front end for a recursion can simplify life. I sometimes do this when the arguments which are most convenient to use are not what I want in the user interface.
Would the following meet your needs?
func checkPalindrome(str: String) -> Bool {
func recursiveTest(var charSet: String.CharacterView) -> Bool {
if charSet.count < 2 {
return true
} else {
if charSet.popFirst() != charSet.popLast() {
return false
} else {
return recursiveTest(charSet)
}
}
}
return recursiveTest(str.characters)
}
just add on more condition in if
func checkPalindrome(word: String) -> Bool {
print(word)
if (word == "" || word.characters.count == 1){
return true
}
else {
if word.characters.first == word.characters.last {
return checkPalindrome(word.substringWithRange(word.startIndex.successor() ..< word.endIndex.predecessor()))
} else {
return false
}
}
}
extension StringProtocol where Self: RangeReplaceableCollection {
var letters: Self { filter(\.isLetter) }
var isPalindrome: Bool {
let letters = self.letters
return String(letters.reversed()).caseInsensitiveCompare(letters) == .orderedSame
}
}
"Dammit I'm Mad".isPalindrome // true
"Socorram-me subi no onibus em marrocos".isPalindrome // true
You can also break your string into an array of characters and iterate through them until its half comparing one by one with its counterpart:
func checkPalindrome(_ word: String) -> Bool {
let chars = Array(word.letters.lowercased())
for index in 0..<chars.count/2 {
if chars[index] != chars[chars.count - 1 - index] {
return false
}
}
return true
}
And the recursive version fixing the range issue where can't form a range with endIndex < startIndex:
func checkPalindrome<T: StringProtocol>(_ word: T) -> Bool {
let word = word.lowercased()
.components(separatedBy: .punctuationCharacters).joined()
.components(separatedBy: .whitespacesAndNewlines).joined()
if word == "" || word.count == 1 {
return true
} else {
if word.first == word.last {
let start = word.index(word.startIndex,offsetBy: 1, limitedBy: word.endIndex) ?? word.startIndex
let end = word.index(word.endIndex,offsetBy: -1, limitedBy: word.startIndex) ?? word.endIndex
return checkPalindrome(word[start..<end])
} else {
return false
}
}
}
checkPalindrome("Dammit I'm Mad")
I think if you make an extension to String like this one then it will make your life easier:
extension String {
var length: Int { return characters.count }
subscript(index: Int) -> Character {
return self[startIndex.advancedBy(index)]
}
subscript(range: Range<Int>) -> String {
return self[Range<Index>(start: startIndex.advancedBy(range.startIndex), end: startIndex.advancedBy(range.endIndex))]
}
}
With it in place, you can change your function to this:
func checkPalindrome(word: String) -> Bool {
if word.length < 2 {
return true
}
if word.characters.first != word.characters.last {
return false
}
return checkPalindrome(word[1..<word.length - 1])
}
Quick test:
print(checkPalindrome("aba")) // Prints "true"
print(checkPalindrome("abc")) // Prints "false"
extension String {
func trimmingFirstAndLastCharacters() -> String {
guard let startIndex = index(self.startIndex, offsetBy: 1, limitedBy: self.endIndex) else {
return self
}
guard let endIndex = index(self.endIndex, offsetBy: -1, limitedBy: self.startIndex) else {
return self
}
guard endIndex >= startIndex else {
return self
}
return String(self[startIndex..<endIndex])
}
var isPalindrome: Bool {
guard count > 1 else {
return true
}
return first == last && trimmingFirstAndLastCharacters().isPalindrome
}
}
We first declare a function that removes first and last characters from a string.
Next we declare a computer property which will contain the actual recursive code that checks if a string is palindrome.
If string's size is less than or equal 1 we immediately return true (strings composed by one character like "a" or the empty string "" are considered palindrome), otherwise we check if first and last characters of the string are the same and we recursively call isPalindrome on the current string deprived of the first and last characters.
Convert the string into an Array. When the loop is executed get the first index and compare with the last index.
func palindrome(string: String)-> Bool{
let char = Array(string)
for i in 0..<char.count / 2 {
if char[i] != char[char.count - 1 - i] {
return false
}
}
return true
}
This solution is not recursive, but it is a O(n) pure index based solution without filtering anything and without creating new objects. Non-letter characters are ignored as well.
It uses two indexes and walks outside in from both sides.
I admit that the extension type and property name is stolen from Leo, I apologize. 😉
extension StringProtocol where Self: RangeReplaceableCollection {
var isPalindrome : Bool {
if isEmpty { return false }
if index(after: startIndex) == endIndex { return true }
var forward = startIndex
var backward = endIndex
while forward < backward {
repeat { formIndex(before: &backward) } while !self[backward].isLetter
if self[forward].lowercased() != self[backward].lowercased() { return false }
repeat { formIndex(after: &forward) } while !self[forward].isLetter
}
return true
}
}
Wasn't really thinking of this, but I think I came up with a pretty cool extension, and thought I'd share.
extension String {
var subString: (Int?) -> (Int?) -> String {
return { (start) in
{ (end) in
let startIndex = start ?? 0 < 0 ? self.endIndex.advancedBy(start!) : self.startIndex.advancedBy(start ?? 0)
let endIndex = end ?? self.characters.count < 0 ? self.endIndex.advancedBy(end!) : self.startIndex.advancedBy(end ?? self.characters.count)
return startIndex > endIndex ? "" : self.substringWithRange(startIndex ..< endIndex)
}
}
}
}
let test = ["Eye", "Pop", "Noon", "Level", "Radar", "Kayak", "Rotator", "Redivider", "Detartrated", "Tattarrattat", "Aibohphobia", "Eve", "Bob", "Otto", "Anna", "Hannah", "Evil olive", "Mirror rim", "Stack cats", "Doom mood", "Rise to vote sir", "Step on no pets", "Never odd or even", "A nut for a jar of tuna", "No lemon, no melon", "Some men interpret nine memos", "Gateman sees name, garageman sees nametag"]
func checkPalindrome(word: String) -> Bool {
if word.isEmpty { return true }
else {
if word.subString(nil)(1) == word.subString(-1)(nil) {
return checkPalindrome(word.subString(1)(-1))
} else {
return false
}
}
}
for item in test.map({ $0.lowercaseString.stringByReplacingOccurrencesOfString(",", withString: "").stringByReplacingOccurrencesOfString(" ", withString: "") }) {
if !checkPalindrome(item) {
print(item)
}
}
A simple solution in Swift:
func isPalindrome(word: String) -> Bool {
// If no string found, return false
if word.count == 0 { return false }
var index = 0
var characters = Array(word) // make array of characters
while index < characters.count / 2 { // repeat loop only for half length of given string
if characters[index] != characters[(characters.count - 1) - index] {
return false
}
index += 1
}
return true
}
func checkPalindrome(_ inputString: String) -> Bool {
if inputString.count % 2 == 0 {
return false
} else if inputString.count == 1 {
return true
} else {
var stringCount = inputString.count
while stringCount != 1 {
if inputString.first == inputString.last {
stringCount -= 2
} else {
continue
}
}
if stringCount == 1 {
return true
} else {
return false
}
}
}

Evaluating Swift's Bool? for true/false/nil in one line?

I've got a lot of code like this:
if let x = optbool {
return f(x)
} else {
return false
}
Can this be expressed on a single line?
The following statement is equivalent to your code:
return optbool.map(f) ?? false
If optbool == nil then .map(f) returns nil,
and the nil-coalescing operator ?? false changes that
to false.
If optbool != nil then .map(f) returns f(optbool!),
which is also the result of the nil-coalescing operator.
Try this:
return optbool != nil ? f(optbool!) : false
your code is valid only if func f(x:Bool)->Bool
func foo(b: Bool?)-> Bool {
if let x = b {
return f(x)
} else {
return false
}
}
now the question has no logic more ... and you can use one of this
let res1 = f(b ?? false)
let res2 = f(b ?? true)
let res3 = !f(b ?? false)
let res4 = !f(b ?? true)
depending on your f function
If you define the f function as an extension of Bool:
extension Bool {
func f() -> Bool {
return true // or false..
}
}
then you can write
return x?.f() ?? false
or
return x?.f() == true
If your question is really:
Can this be expressed on a single line?
The answer is undoubtedly YES:
if let x = optbool { return f(x) } else { return false }
;-)
Seriously, if optbool is not supposed to be nil, I would rather write it on 2 lines:
guard let x = optbool else { return false }
return f(x)