Swift 4: Formatting number's into friendly K's
This answer formats by truncating (versus rounding). 1,515
rounded would generate 2k
whereas truncated would generate 1.5k
. The function requires reducing a number's scale (removing digits to the right of the decimal) which I've just packaged as an extension so it can be used anywhere (not just in the function).
extension Double {
func reduceScale(to places: Int) -> Double {
let multiplier = pow(10, Double(places))
let newDecimal = multiplier * self // move the decimal right
let truncated = Double(Int(newDecimal)) // drop the fraction
let originalDecimal = truncated / multiplier // move the decimal back
return originalDecimal
}
}
func formatNumber(_ n: Int) -> String {
let num = abs(Double(n))
let sign = (n < 0) ? "-" : ""
switch num {
case 1_000_000_000...:
var formatted = num / 1_000_000_000
formatted = formatted.reduceScale(to: 1)
return "\(sign)\(formatted)B"
case 1_000_000...:
var formatted = num / 1_000_000
formatted = formatted.reduceScale(to: 1)
return "\(sign)\(formatted)M"
case 1_000...:
var formatted = num / 1_000
formatted = formatted.reduceScale(to: 1)
return "\(sign)\(formatted)K"
case 0...:
return "\(n)"
default:
return "\(sign)\(n)"
}
}
You can fine tune this method for specific cases, such as returning 100k
instead of 100.5k
or 1M
instead of 1.1M
. This method handles negatives as well.
print(formatNumber(1515)) // 1.5K
print(formatNumber(999999)) // 999.9K
print(formatNumber(1000999)) // 1.0M
The following logic of if-else
statements shows you what goes first and what last:
func formatPoints(from: Int) -> String {
let number = Double(from)
let thousand = number / 1000
let million = number / 1000000
let billion = number / 1000000000
if billion >= 1.0 {
return "\(round(billion*10)/10)B"
} else if million >= 1.0 {
return "\(round(million*10)/10)M"
} else if thousand >= 1.0 {
return ("\(round(thousand*10/10))K")
} else {
return "\(Int(number))"
}
}
print(formatPoints(1000)) /* 1.0 K */
print(formatPoints(1000000)) /* 1.0 M */
print(formatPoints(1000000000)) /* 1.0 B */
Billion must go first.