We're trying to write a simple gain/loss function to return a color based on a value relative to zero. If it's positive, we return green. If negative, we return red. If zero, we return gray.
The current function is written specifically to take a double, like so:
func getChangeColor(value:Double) -> UIColor {
if value > 0 {
return Theme.Colors.gain
} else if value < 0 {
return Theme.Colors.loss
} else {
return Theme.Colors.noChange
}
}
But I'm wondering if it can be updated to take any numeric value?
My first thought was to write it against Comparable
but the problem is we need to compare it against zero in that same type, whatever it is.
In other languages like C#, you can get the default value for a type, which in the case of numerics, is zero. Does Swift have anything similar? If so, we could do this...
func getChangeColor<T:Comparable>(value:T) -> UIColor {
let defaultValue = default(T.self)
if value > defaultValue {
return Theme.Colors.gain
} else if value < defaultValue {
return Theme.Colors.loss
} else {
return Theme.Colors.noChange
}
}
...or is this approach wrong in the first place?
My solution adds a second protocol conformance: Numeric
provides basic arithmetic operators for scalar types.
Then you are able to calculate the zero value in the generic type
func getChangeColor<T : Comparable & Numeric>(value:T) -> UIColor {
let zero = value - value
if value > zero {
return Theme.Colors.gain
} else if value < zero {
return Theme.Colors.loss
} else {
return Theme.Colors.noChange
}
}
or with a switch
statement
func getChangeColor<T : Comparable & Numeric>(value:T) -> UIColor {
let zero = value - value
switch value {
case zero: return Theme.Colors.noChange
case zero...: return Theme.Colors.gain
default: return Theme.Colors.loss
}
}
or with the ternary operator (added by OP)
func getChangeColor<T : Comparable & Numeric>(value:T) -> UIColor {
let zero = value - value
return value > zero
? Theme.Colors.gain
: value < zero
? Theme.Colors.loss
: Theme.Colors.noChange
}