Substrings
Prefix && Suffix (Thank primo)
let str = "Hello! World"
str.prefix(6) // "Hello!"
str.suffix(5) // "World"
Splitting
The split function can take a closure that tells it what characters to split on. Split on spaces using
i.split{$0==" "}
Typecasting
String
String(i)
can be
"\(i)"
Array
Array(i)
can be
[]+i
Looping
for i in 0...100{print(i)}
(0...100).map{print($0)}
Depending on how many times you use the loop variable, it might be shorter to use for
-in
instead of map
in certain cases. Try them both!
Conditional printing
Usually the same length, but depending on specific situation one can be shorter than the other
if a>0{print(a)}
a>0 ?print(a):()
Argument labels
By wrapping a function or initializer reference in an immediately-executed closure, you can call it without argument labels:
String(repeating:"h",count:3)
{String.init}()("h",3)
["a","b","c"].joined(separator:" ")
{["a","b","c"].joined}()(" ")
This trick works for most functions/initializers with lengthy argument labels, as long as the labels aren't necessary for the compiler to resolve overloads.
Key paths
"hello".map{$0.asciiValue!}
"hello".map(\.asciiValue!)
Type inference
Type placeholders
In cases where the compiler can't infer the full type, it can often infer part of the type:
let f={($0 as[String]).map{$0+"hello"}}
let g={$0.map{$0+"hello"}} // error: cannot infer type of closure parameter '$0' without a type annotation
let h={($0 as[_]).map{$0+"hello"}}
This syntax works for generic parameters; Array
, Dictionary
, and Optional
sugar ([_]
, [_:_]
, _?
); tuple types; and function types.
Inference via literals
let f={($0,$1,$2)as(Int,String,Double)}
let g={($0+0,$1+"",$2+0.0)}
(If you do this too much, you can very easily time-out the type checker -- sprinkling some explicit type annotations here and there can help.)