Try to return in ternary expression - ios

I have a Swift application.
I'm getting the error Expected expression after '?' in ternary expression from Xcode compiler
in
private func getContentPre(highlight: Highlight) -> String!
{
highlight.contentPre.count == 0 ? return ">" : return highlight.contentPre
}
Apple docs says:
why isn't it possible to return in ternary expression like using if statement?

You should re-write your function like this. This will evaluate the count of the contentPre variable and return the appropriate response.
private func getContentPre(highlight: Highlight) -> String! {
return highlight.contentPre.count == 0 ? ">" : highlight.contentPre
}
However as it would appear that contentPre would be a String you should use .isEmpty as it is more performant that checking the length of a String
private func getContentPre(highlight: Highlight) -> String! {
return highlight.contentPre.isEmpty ? ">" : highlight.contentPre
}

return does not return anything - I mean, to the function what calls it. Ternary operator's parameters must be expressions.

Related

Swift String API Alternate for HackerRank

So I'm trying to prepare myself for coding interviews by doing HackerRank's test case samples. If you're familiar with the process, you usually take a standard input that has various lines of strings and you extract the information based on what the question is asking. I have come across numerous questions where they will give you a line (as a String) with n number of integers separated by a space (i.e. 1 2 3 4 5). In order to solve the problem I need to extrapolate an array of Int ([Int]) from a String. I came up with this nifty method:
func extractIntegers(_ s: String) -> [Int] {
let splits = s.characters.split { [" "].contains(String($0)) }
return splits.map { Int(String($0).trimmingCharacters(in: .whitespaces))! }
}
So I code it in my Playground and it works fantastic, I even run multiple test cases I make up, and they all pass with flying colors...then I copy the code to HackerRank and try running it for submission. And I get this:
solution.swift:16:29: error: value of type 'String' has no member 'trimmingCharacters'
return splits.map { Int(String($0).trimmingCharacters(in: .whitespaces))! }
So... okay maybe HR hasn't updated everything for Swift 3 yet. No big deal! I have an idea for an even cleaner solution! Here it is:
func extractIntegers(_ s: String) -> [Int] {
return s.components(separatedBy: " ").map { Int($0)! }
}
....AAAAANDDD of course:
solution.swift:15:12: error: value of type 'String' has no member 'components'
return s.components(separatedBy: " ").map { Int($0)! }
So now I'm forced to use a really sloppy method where I loop through all the characters, check for spaces, append substrings from ranges between spaces into an array, and then map that array and return it.
Does anyone have any other clean ideas to work around HR's inadequacies with Swift? I would like any recommendations I can get!
Thanks in advance!
The String methods
func trimmingCharacters(in set: CharacterSet) -> String
func components(separatedBy separator: String) -> [String]
are actually methods of the NSString class, defined in the Foundation
framework, and "bridged" to Swift. Therefore, to make your code compile,
you have go add
import Foundation
But a slightly simplified version of your first method compiles
with pure Swift, without importing Foundation. I handles leading, trailing, and intermediate whitespace:
func extractIntegers(_ s: String) -> [Int] {
let splits = s.characters.split(separator: " ").map(String.init)
return splits.map { Int($0)! }
}
let a = extractIntegers(" 12 234 -567 4 ")
print(a) // [12, 234, -567, 4]
Update for Swift 4 (and simplified):
func extractIntegers(_ s: String) -> [Int] {
return s.split(separator: " ").compactMap { Int($0) }
}

Swift: Precedence for custom operator in relation to dot (".") literal

In Swift 3, I have written a custom operator prefix operator § which I use in a method taking a String as value returning a LocalizedString struct (holding key and value).
public prefix func §(key: String) -> LocalizedString {
return LocalizedString(key: key)
}
public struct LocalizedString {
public var key: String
public var value: String
public init(key: String) {
let translated = translate(using: key) // assume we have this
self.key = key
self.value = translated ?? "!!\(key)!!"
}
}
(Yes I know about the awesome L10n enum in SwiftGen, but we are downloading our strings from our backend, and this question is more about how to work with custom operators)
But what if we wanna get the translated value from the result of the § operator (i.e. the property value from the resulting LocalizedString)
let translation = §"MyKey".value // Compile error "Value of type 'String' has no member 'value'"
We can of course easily fix this compile error by wraping it in parenthesis (§"MyKey").value. But if do not want to do that. Is it possible to set precedence for custom operators in relationship to the 'dot' literal?
Yes I know that only infix operators may declare precedence, but it would make sense to somehow work with precedence in order to achieve what I want:
precedencegroup Localization { higherThan: DotPrecedence } // There is no such group as "Dot"
prefix operator §: Localization
To mark that the Swift compiler first should evaluate §"MyKey" and understand that is not a string, but in fact an LocalizedString (struct).
Feels unlikely that this would be impossible? What am I missing?
The . is not an operator like all the other ones defined in the standard library, it is provided by the compiler instead. The grammar for it are Explicit Member Expressions.
Having a higher precedence than the . is nothing the compiler should enable you to do, as it's such a fundamental use case. Imagine what you could do if the compiler enabled such a thing:
-"Test".characters.count
If you could have a higher precedence than ., the compiler has to check all possibilities:
(-"Test").characters.count // func -(s: String) -> String
(-("Test".characters)).count // func -(s: String.CharacterView) -> String.CharacterView
-("Test".characters.count) // func -(s: Int) -> Int
Which would
Potentially increase the compile time a lot
Be ambiguous
Possibly change behaviour of existing code upon adding overloads
What I suggest you to do is abandon the idea with a new operator, it's only going to be adding more cognitive load by squashing some specific behaviour into a single obscure character. This is how I'd do it:
extension String {
var translatedString : String {
return translate(using: self)
}
}
"MyKey".localizedString
Or if you want to use your LocalizedString:
extension String {
var localized : LocalizedString {
return LocalizedString(key: self)
}
}
"MyKey".localized.value
These versions are much more comprehensive.

Comparing type of Generic associated type in Swift

I have the next code:
protocol Flyable {
var airspeedVelocity: Double { get }
}
func topSpeed<T: CollectionType where T.Generator.Element == Flyable>(collection: T) -> Double {
return collection.map { $0.airspeedVelocity }.reduce(0) { max($0, $1) }
}
I understood, by reading the Swift Documentation that:
You write a where clause by placing the where keyword immediately after the list of type parameters, followed by constraints for associated types or equality relationships between types and associated types.
This is the example given on the docs:
func allItemsMatch<C1: Container, C2: Container where
C1.ItemType == C2.ItemType, C1.ItemType: Equatable>
(someContainer: C1, _ anotherContainer: C2) -> Bool {
// code
}
Note that when expressing that the associated type ItemType of the C1 type must conform to Equatable protocol you use : and not ==, why is that not the case in my example, where I have to use == to state that the Element associated type of T.Generator must conform with Flyable?
When changing == with : the compiler complains with this:
error: cannot invoke 'topSpeed' with an argument list of type '([Flyable])' note: expected an argument list of type '(T)'
You can achieve this without using Generics.
protocol Flyable {
var airspeedVelocity: Double { get }
}
func topSpeed(collection: [Flyable]) -> Double {
return collection.map { $0.airspeedVelocity }.reduce(0) { max($0, $1) }
}
class Airplane: Flyable {
var airspeedVelocity: Double = 10
}
class Rocket: Flyable {
var airspeedVelocity: Double = 50
}
topSpeed([Airplane(),Rocket()]) //50
I've found the reason here. The where clause has the next grammar:
conformance-requirement → type-identifier­:­type-identifier­
same-type-requirement → type-identifier­==­type­
So, when you want to state that your type parameter conforms to certain protocol you use :. BUT, when you want your type to be exactly of a certain type, you use ==. In my example, I wanted to take as a parameter a collection of Flyable. So, when trying to use : the compiler complained because Flyable doesn't conform to Flyable. Flyable IS Flyable, thus I must use == (or do something like what #Rahul Katariya answered)

Operator Priority in Swift

I just spent a frustrating few hours trying to debug code some, through a process of elimination I was able to fix the problem but I can't figure out the cause and its bugging me just as much.
So a bit of context: we want to filter an array of objects (which we will just refer to as type Object) based on a collection of predicates of type Object -> Bool. We first combine all the predicates into a composed function and then use the filter function with our composed predicate to get the filtered array of objects. So heres an example:
var predicateA: (Object -> Bool) = { (obj) in obj.isFoo }
var predicateB: (Object -> Bool) = { (obj) in obj.isBar }
var composedPredicate: (Object -> Bool) {
return { (obj) in
return predicateA(obj) && predicateB(obj)
}
}
The above example works perfectly but when try to introduce an optional for the predicates, it doesn't work as expected.
var predicateA: (Object -> Bool) = { (obj) in obj.isFoo }
var optionalPredicateB: (Object -> Bool)? = nil
var composedPredicate: (Object -> Bool) {
return { (obj) in
return predicateA(obj)
&& optionalPredicateB != nil ? optionalPredicateB!(obj) : true
}
}
So the code above will cause the composedPredicate to always return true even if the one of the "sub-predicates" return false.
This can be fixed by changing the optionPredicateLine to include parans
&& (optionalPredicateB != nil ? optionalPredicateB!(obj) : true)
EDIT:
I believe the error is due to the priority on the operators in the ternary operator i.e. it is evaluating all the && statements before the ? in the ternary operator when determining which case to use.
Although I'm not 100% sure on this so i am looking for clarification / or if the cause is something else.
You can find the precedence of the operators here. It shows "&&" has a precedence of 120, whereas "?:" has a precedence of 100, and "!=" is 130. Therefore the "&&" is being evaluated before the ternary operator, which is the equivalent of:
return (predicateA(obj) && (optionalPredicateB != nil)) ? optionalPredicateB!(obj) : true
You can find the Swift list of infix operators here. They are ordered by decreasing order of precedence.
In this line
return predicateA(obj)
&& optionalPredicateB != nil ? optionalPredicateB!(obj) : true
Compiler is taking
predicateA(obj)
&& optionalPredicateB != nil
as a condition for ternary that's why it was not working so now you added braces so it is working fine

When should I compare an optional value to nil?

Quite often, you need to write code such as the following:
if someOptional != nil {
// do something with the unwrapped someOptional e.g.
someFunction(someOptional!)
}
This seems a bit verbose, and also I hear that using the ! force unwrap operator can be unsafe and best avoided. Is there a better way to handle this?
It is almost always unnecessary to check if an optional is not nil. Pretty much the only time you need to do this is if its nil-ness is the only thing you want to know about – you don’t care what’s in the value, just that it’s not nil.
Under most other circumstances, there is a bit of Swift shorthand that can more safely and concisely do the task inside the if for you.
Using the value if it isn’t nil
Instead of:
let s = "1"
let i = Int(s)
if i != nil {
print(i! + 1)
}
you can use if let:
if let i = Int(s) {
print(i + 1)
}
You can also use var:
if var i = Int(s) {
print(++i) // prints 2
}
but note that i will be a local copy - any changes to i will not affect the value inside the original optional.
You can unwrap multiple optionals within a single if let, and later ones can depend on earlier ones:
if let url = NSURL(string: urlString),
data = NSData(contentsOfURL: url),
image = UIImage(data: data)
{
let view = UIImageView(image: image)
// etc.
}
You can also add where clauses to the unwrapped values:
if let url = NSURL(string: urlString) where url.pathExtension == "png",
let data = NSData(contentsOfURL: url), image = UIImage(data: data)
{ etc. }
Replacing nil with a default
Instead of:
let j: Int
if i != nil {
j = i
}
else {
j = 0
}
or:
let j = i != nil ? i! : 0
you can use the nil-coalescing operator, ??:
// j will be the unwrapped value of i,
// or 0 if i is nil
let j = i ?? 0
Equating an optional with a non-optional
Instead of:
if i != nil && i! == 2 {
print("i is two and not nil")
}
you can check if optionals are equal to non-optional values:
if i == 2 {
print("i is two and not nil")
}
This also works with comparisons:
if i < 5 { }
nil is always equal to other nils, and is less than any non-nil value.
Be careful! There can be gotchas here:
let a: Any = "hello"
let b: Any = "goodbye"
if (a as? Double) == (b as? Double) {
print("these will be equal because both nil...")
}
Calling a method (or reading a property) on an optional
Instead of:
let j: Int
if i != nil {
j = i.successor()
}
else {
// no reasonable action to take at this point
fatalError("no idea what to do now...")
}
you can use optional chaining, ?.:
let j = i?.successor()
Note, j will also now be optional, to account for the fatalError scenario. Later, you can use one of the other techniques in this answer to handle j’s optionality, but you can often defer actually unwrapping your optionals until much later, or sometimes not at all.
As the name implies, you can chain them, so you can write:
let j = s.toInt()?.successor()?.successor()
Optional chaining also works with subscripts:
let dictOfArrays: ["nine": [0,1,2,3,4,5,6,7]]
let sevenOfNine = dictOfArrays["nine"]?[7] // returns {Some 7}
and functions:
let dictOfFuncs: [String:(Int,Int)->Int] = [
"add":(+),
"subtract":(-)
]
dictOfFuncs["add"]?(1,1) // returns {Some 2}
Assigning to a property on an optional
Instead of:
if splitViewController != nil {
splitViewController!.delegate = self
}
you can assign through an optional chain:
splitViewController?.delegate = self
Only if splitViewController is non-nil will the assignment happen.
Using the value if it isn’t nil, or bailing (new in Swift 2.0)
Sometimes in a function, there’s a short bit of code you want to write to check an optional, and if it’s nil, exit the function early, otherwise keep going.
You might write this like this:
func f(s: String) {
let i = Int(s)
if i == nil { fatalError("Input must be a number") }
print(i! + 1)
}
or to avoid the force unwrap, like this:
func f(s: String) {
if let i = Int(s) {
print(i! + 1)
}
else {
fatalErrr("Input must be a number")
}
}
but it’s much nicer to keep the error-handling code at the top by the check. This can also lead to unpleasant nesting (the "pyramid of doom").
Instead you can use guard, which is like an if not let:
func f(s: String) {
guard let i = Int(s)
else { fatalError("Input must be a number") }
// i will be an non-optional Int
print(i+1)
}
The else part must exit the scope of the guarded value, e.g. a return or fatalError, to guarantee that the guarded value will be valid for the remainder of the scope.
guard isn’t limited to function scope. For example the following:
var a = ["0","1","foo","2"]
while !a.isEmpty {
guard let i = Int(a.removeLast())
else { continue }
print(i+1, appendNewline: false)
}
prints 321.
Looping over non-nil items in a sequence (new in Swift 2.0)
If you have a sequence of optionals, you can use for case let _? to iterate over all the non-optional elements:
let a = ["0","1","foo","2"]
for case let i? in a.map({ Int($0)}) {
print(i+1, appendNewline: false)
}
prints 321. This is using the pattern-matching syntax for an optional, which is a variable name followed by ?.
You can also use this pattern matching in switch statements:
func add(i: Int?, _ j: Int?) -> Int? {
switch (i,j) {
case (nil,nil), (_?,nil), (nil,_?):
return nil
case let (x?,y?):
return x + y
}
}
add(1,2) // 3
add(nil, 1) // nil
Looping until a function returns nil
Much like if let, you can also write while let and loop until nil:
while let line = readLine() {
print(line)
}
You can also write while var (similar caveats to if var apply).
where clauses also work here (and terminate the loop, rather than skipping):
while let line = readLine()
where !line.isEmpty {
print(line)
}
Passing an optional into a function that takes a non-optional and returns a result
Instead of:
let j: Int
if i != nil {
j = abs(i!)
}
else {
// no reasonable action to take at this point
fatalError("no idea what to do now...")
}
you can use optional’s map operator:
let j = i.map { abs($0) }
This is very similar to optional chaining, but for when you need to pass the non-optional value into the function as an argument. As with optional chaining, the result will be optional.
This is nice when you want an optional anyway. For example, reduce1 is like reduce, but uses the first value as the seed, returning an optional in case the array is empty. You might write it like this (using the guard keyword from earlier):
extension Array {
func reduce1(combine: (T,T)->T)->T? {
guard let head = self.first
else { return nil }
return dropFirst(self).reduce(head, combine: combine)
}
}
[1,2,3].reduce1(+) // returns 6
But instead you could map the .first property, and return that:
extension Array {
func reduce1(combine: (T,T)->T)->T? {
return self.first.map {
dropFirst(self).reduce($0, combine: combine)
}
}
}
Passing an optional into a function that takes an optional and returns a result, avoiding annoying double-optionals
Sometimes, you want something similar to map, but the function you want to call itself returns an optional. For example:
// an array of arrays
let arr = [[1,2,3],[4,5,6]]
// .first returns an optional of the first element of the array
// (optional because the array could be empty, in which case it's nil)
let fst = arr.first // fst is now [Int]?, an optional array of ints
// now, if we want to find the index of the value 2, we could use map and find
let idx = fst.map { find($0, 2) }
But now idx is of type Int??, a double-optional. Instead, you can use flatMap, which “flattens” the result into a single optional:
let idx = fst.flatMap { find($0, 2) }
// idx will be of type Int?
// and not Int?? unlike if `map` was used
I think you should go back to the Swift programming book and learn what these things are for. ! is used when you are absolutely sure that the optional isn't nil. Since you declared that you are absolutely sure, it crashes if you're wrong. Which is entirely intentional. It is "unsafe and best avoided" in the sense that asserts in your code are "unsafe and best avoided". For example:
if someOptional != nil {
someFunction(someOptional!)
}
The ! is absolutely safe. Unless there is a big blunder in your code, like writing by mistake (I hope you spot the bug)
if someOptional != nil {
someFunction(SomeOptional!)
}
in which case your app may crash, you investigate why it crashes, and you fix the bug - which is exactly what the crash is there for. One goal in Swift is that obviously your app should work correctly, but since Swift cannot enforce this, it enforces that your app either works correctly or crashes if possible, so bugs get removed before the app ships.
You there is one way. It is called Optional Chaining. From documentation:
Optional chaining is a process for querying and calling properties,
methods, and subscripts on an optional that might currently be nil. If
the optional contains a value, the property, method, or subscript call
succeeds; if the optional is nil, the property, method, or subscript
call returns nil. Multiple queries can be chained together, and the
entire chain fails gracefully if any link in the chain is nil.
Here is some example
class Person {
var residence: Residence?
}
class Residence {
var numberOfRooms = 1
}
let john = Person()
if let roomCount = john.residence?.numberOfRooms {
println("John's residence has \(roomCount) room(s).")
} else {
println("Unable to retrieve the number of rooms.")
}
// prints "Unable to retrieve the number of rooms."
You can check the full article here.
We can use optional binding.
var x:Int?
if let y = x {
// x was not nil, and its value is now stored in y
}
else {
// x was nil
}
After lot of thinking and researching i have came up with the easiest way to unwrap an optional :
Create a new Swift File and name it UnwrapOperator.swift
Paste the following code in the file :
import Foundation
import UIKit
protocol OptionalType { init() }
extension String: OptionalType {}
extension Int: OptionalType {}
extension Int64: OptionalType {}
extension Float: OptionalType {}
extension Double: OptionalType {}
extension CGFloat: OptionalType {}
extension Bool: OptionalType {}
extension UIImage : OptionalType {}
extension IndexPath : OptionalType {}
extension NSNumber : OptionalType {}
extension Date : OptionalType {}
extension UIViewController : OptionalType {}
postfix operator *?
postfix func *?<T: OptionalType>( lhs: T?) -> T {
guard let validLhs = lhs else { return T() }
return validLhs
}
prefix operator /
prefix func /<T: OptionalType>( rhs: T?) -> T {
guard let validRhs = rhs else { return T() }
return validRhs
}
Now the above code has created 2 operator [One prefix and one postfix].
At the time of unwrapping you can use either of these operator before or after the optionals
The explanation is simple, the operators returns the constructor value if they get nil in variable else the contained value inside the variable.
Below is the example of usage :
var a_optional : String? = "abc"
var b_optional : Int? = 123
// before the usage of Operators
print(a_optional) --> Optional("abc")
print(b_optional) --> Optional(123)
// Prefix Operator Usage
print(/a_optional) --> "abc"
print(/b_optional) --> 123
// Postfix Operator Usage
print(a_optional*?) --> "abc"
print(b_optional*?) --> 123
Below is the example when variable contains nil :
var a_optional : String? = nil
var b_optional : Int? = nil
// before the usage of Operators
print(a_optional) --> nil
print(b_optional) --> nil
// Prefix Operator Usage
print(/a_optional) --> ""
print(/b_optional) --> 0
// Postfix Operator Usage
print(a_optional*?) --> ""
print(b_optional*?) --> 0
Now it is your choice which operator you use, both serve the same purpose.

Resources