【问题标题】:Swift 4: Formatting number's into friendly K'sSwift 4:将数字格式化为友好的 K
【发布时间】:2018-01-21 19:57:57
【问题描述】:

目前正在开发一个对我来说非常有用的简单功能..

例如: 如果我有 1000 个,它将打印出 1.0K,或者 1,000,000 将是 1M,直到这里一切正常,

如果我想把1,000,000,000变成1B呢?

我尝试了以下 ->

func formatPoints(from: Int) -> String {
     let number = Double(from)
     let thousand = number / 1000
     let million = number / 1000000
     let billion = number / 1000000000

     if million >= 1.0 { 
     return "\(round(million*10)/10)M" 
} else if thousand >= 1.0 { 
     return "\(round(thousand*10)/10)K"
} else if billion >= 1.0 {
        return ("\(round(billion*10/10))B")
} else {
    return "\(Int(number))"}
}

print(formatPoints(from: 1000000000))

但它返回1000.0M,而不是1B

谢谢!

【问题讨论】:

  • 那是因为你先检查数百万。
  • 你的逻辑没有多大意义。为什么对于 1000 它使用 minimumFraction 数字 = 1 (1.0K) 而对于 1_000_000 它使用 0 (1M)?

标签: swift


【解决方案1】:

此答案通过截断(相对于舍入)格式化。 1,515 舍入将生成 2k,而截断将生成 1.5k。该函数需要减少我刚刚打包为扩展的数字比例(删除小数点右侧的数字),以便它可以在任何地方使用(不仅仅是在函数中)。

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)"
    }
}

您可以针对特定情况微调此方法,例如返回100k 而不是100.5k1M 而不是1.1M。此方法也可以处理负数。

print(formatNumber(1515)) // 1.5K
print(formatNumber(999999)) // 999.9K
print(formatNumber(1000999)) // 1.0M

【讨论】:

  • 很好的答案,我也喜欢这种方式
  • 如果按降序排列,只需写case 1_000_000_000...case 1_000_000...case 1_000...。另外,您只需提取符号:let sign = (n &lt; 0) ? "-" : "",然后返回 return "\(sign)\(formatted)X"
  • @iabuseservers 您应该在formatted 的初始定义周围加上括号(当时它实际上并没有格式化!),然后直接在其上调用 truncate。 return "\(sign)\((num / 1_000).truncate(places: 1))K"
【解决方案2】:

if-else 语句的以下逻辑向您展示了先执行后执行的操作:

import Foundation

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(from: 1000))             /*  1.0 K  */
print(formatPoints(from: 1000000))          /*  1.0 M  */
print(formatPoints(from: 1000000000))       /*  1.0 B  */

十亿必须先走。

【讨论】:

  • round() 是 Foundation 模块(或 Swift 标准库)中的实例方法。
猜你喜欢
  • 1970-01-01
  • 2013-02-03
  • 2017-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-12
  • 2023-03-27
  • 1970-01-01
相关资源
最近更新 更多