Reputation: 1
I have a closure that adds zero to left part of a number in a condition and return String. The number type is Int but it must work if the Type is optional Int.
I ended up to repeat my code, my goal is stop repeating my code in the way that my code works for Int
and Int?
extension Int {
var addLeftZero: String { addLeftZeroClosure(self) }
}
extension Optional where Wrapped == Int {
var addLeftZero: String {
if let unwrappedValue: Wrapped = self { return addLeftZeroClosure(unwrappedValue) }
else { return "00" }
}
}
let addLeftZeroClosure: (Int) -> String = { value in
if (value >= 10) { return String(describing: value) }
else { return "0" + String(describing: value) }
}
Upvotes: 0
Views: 59
Reputation: 30431
Read both parts first, before picking solution to use.
You could do something like this:
extension Int {
var addLeftZero: String {
String(format: "%02d", self)
}
}
extension Optional where Wrapped == Int {
var addLeftZero: String {
self?.addLeftZero ?? "00"
}
}
Example usage:
let a: Int = 1
let b: Int? = 2
let c: Int? = nil
print(a.addLeftZero) // Prints: 01
print(b.addLeftZero) // Prints: 02
print(c.addLeftZero) // Prints: 00
Although Xcode code-completion will automatically do a?.addLeftZero
instead of a.addLeftZero
.
A (possibly) better way would be to have this abstracted away in your own custom type:
struct PaddedNumber: ExpressibleByIntegerLiteral, ExpressibleByNilLiteral {
let value: Int?
var string: String {
if let value = value {
return String(format: "%02d", value)
} else {
return "00"
}
}
init(_ value: Int?) {
self.value = value
}
init(integerLiteral value: IntegerLiteralType) {
self.value = value
}
init(nilLiteral: ()) {
value = nil
}
}
Example usage:
let a: PaddedNumber = 1
let b: PaddedNumber = 2
let c: PaddedNumber = nil
print(a.string) // Prints: 01
print(b.string) // Prints: 02
print(c.string) // Prints: 00
Upvotes: 1