Swift 2.0将1000格式化为友好的K.

我正在尝试编写一个函数来向K和M提供数千和数百万例如:

1000 = 1k 1100 = 1.1k 15000 = 15k 115000 = 115k 1000000 = 1m 

这是我到目前为止的地方:

 func formatPoints(num: Int) -> String { let newNum = String(num / 1000) var newNumString = "\(num)" if num > 1000 && num  1000000 { newNumString = "\(newNum)m" } return newNumString } formatPoints(51100) // THIS RETURNS 51K instead of 51.1K 

如何让这个function起作用,我缺少什么?

 func formatPoints(num: Double) ->String{ let thousandNum = num/1000 let millionNum = num/1000000 if num >= 1000 && num < 1000000{ if(floor(thousandNum) == thousandNum){ return("\(Int(thousandNum))k") } return("\(thousandNum.roundToPlaces(1))k") } if num > 1000000{ if(floor(millionNum) == millionNum){ return("\(Int(thousandNum))k") } return ("\(millionNum.roundToPlaces(1))M") } else{ if(floor(num) == num){ return ("\(Int(num))") } return ("\(num)") } } extension Double { /// Rounds the double to decimal places value func roundToPlaces(places:Int) -> Double { let divisor = pow(10.0, Double(places)) return round(self * divisor) / divisor } } 

如果数字是完整的,更新的代码现在应该不返回.0。 现在应该输出1k而不是1.0k。 我只是检查了双倍和它的地板是否相同。

我在这个问题中找到了双扩展:在flash中将double值舍入为x个小数位数

以下扩展如下 –

  1. 将数字10456显示为10.5k,将10006显示为10k(不显示.0小数)。
  2. 将对数百万的确切做以上并格式化,即10.5M和10M
  3. 将以货币格式格式化数千到9999,即使用逗号9,999

     extension Double { var kmFormatted: String { if self >= 10000, self <= 999999 { return String(format: "%.1fK", locale: Locale.current,self/1000).replacingOccurrences(of: ".0", with: "") } if self > 999999 { return String(format: "%.1fM", locale: Locale.current,self/1000000).replacingOccurrences(of: ".0", with: "") } return String(format: "%.0f", locale: Locale.current,self) } } 

用法:

 let num: Double = 1000001.00 //this should be a Double since the extension is on Double let millionStr = num.kmFormatted print(millionStr) 

打印1M

在这里,它正在行动 –

在此处输入图像描述

 extension Int { var roundedWithAbbreviations: String { let number = Double(self) let thousand = number / 1000 let million = number / 1000000 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(11.roundedWithAbbreviations) // "11" print(11111.roundedWithAbbreviations) // "11.1K" print(11111111.roundedWithAbbreviations) // "11.1 M" 

Swift 3中的上述解决方案(来自@qlear):

 func formatPoints(num: Double) -> String { var thousandNum = num / 1_000 var millionNum = num / 1_000_000 if num >= 1_000 && num < 1_000_000 { if floor(thousandNum) == thousandNum { return("\(Int(thousandNum))k") } return("\(thousandNum.roundToPlaces(1))k") } if num > 1_000_000 { if floor(millionNum) == millionNum { return "\(Int(thousandNum))k" } return "\(millionNum.roundToPlaces(1))M" } else{ if floor(num) == num { return "\(Int(num))" } return "\(num)" } } extension Double { // Rounds the double to decimal places value mutating func roundToPlaces(_ places : Int) -> Double { let divisor = pow(10.0, Double(places)) return (self.rounded() * divisor) / divisor } } 

答案中的一些变化(对于Int和对于百万的正确):

 func formatPoints(num: Int) ->String{ let thousandNum = num/1000 let millionNum = num/1000000 if num >= 1000 && num < 1000000{ if(thousandNum == thousandNum){ return("\(thousandNum)k") } return("\(thousandNum)k") } if num > 1000000{ if(millionNum == millionNum){ return("\(millionNum)M") } return ("\(millionNum)M") } else{ if(num == num){ return ("\(num)") } return ("\(num)") } } 

要添加答案,这里是一个Swift 4.X版本,使用循环可以在必要时轻松添加/删除单位:

 extension Double { var shortStringRepresentation: String { if self.isNaN { return "NaN" } if self.isInfinite { return "\(self < 0.0 ? "-" : "+")Infinity" } let units = ["", "k", "M"] var interval = self var i = 0 while i < units.count - 1 { if abs(interval) < 1000.0 { break } i += 1 interval /= 1000.0 } // + 2 to have one digit after the comma, + 1 to not have any. // Remove the * and the number of digits argument to display all the digits after the comma. return "\(String(format: "%0.*g", Int(log10(interval)) + 2, interval))\(units[i])" } } 

例子:

 $ [1.5, 15, 1000, 1470, 1000000, 1530000, 1791200000].map { $0.shortStringRepresentation } [String] = 7 values { [0] = "1.5" [1] = "15" [2] = "1k" [3] = "1.5k" [4] = "1M" [5] = "1.5M" [6] = "1791.2M" } 

基于@qlear的解决方案。
我注意到如果数字正好是1000000,它将返回1000000未格式化。
所以我已将其添加到函数中。 我还包括负值..因为不是每个人都在赚钱!

 func formatPoints(num: Double) ->String{ let thousandNum = num/1000 let millionNum = num/1000000 if num > 0 { if num >= 1000 && num < 1000000{ if(floor(thousandNum) == thousandNum){ return("\(Int(thousandNum))k") } return("\(round1(thousandNum, toNearest: 0.01))k") } if num > 1000000{ if(floor(millionNum) == millionNum){ return("\(Int(thousandNum))k") } return ("\(round1(millionNum, toNearest: 0.01))M") } else if num == 1000000 { return ("\(round1(millionNum, toNearest: 0.01))M") } else{ if(floor(num) == num){ return ("\(Int(num))") } return ("\(round1(num, toNearest: 0.01))") } } else { if num <= -1000 && num > -1000000{ if(floor(thousandNum) == thousandNum){ return("\(Int(thousandNum))k") } return("\(round1(thousandNum, toNearest: 0.01))k") } if num < -1000000{ if(floor(millionNum) == millionNum){ return("\(Int(thousandNum))k") } return ("\(round1(millionNum, toNearest: 0.01))M") } else if num == -1000000 { return ("\(round1(millionNum, toNearest: 0.01))M") } else{ if(floor(num) == num){ return ("\(Int(num))") } return ("\(round1(num, toNearest: 0.01))") } } } 

当然是数字扩展:

 extension Double { /// Rounds the double to decimal places value func round1(_ value: Double, toNearest: Double) -> Double { return Darwin.round(value / toNearest) * toNearest } } 

@chrisz答案的轻微改进, Swift-4 Doble extension – 在所有情况下都可以正常工作。

 extension Double { // Formatting double value to k and M // 1000 = 1k // 1100 = 1.1k // 15000 = 15k // 115000 = 115k // 1000000 = 1m func formatPoints() -> String{ let thousandNum = self/1000 let millionNum = self/1000000 if self >= 1000 && self < 1000000{ if(floor(thousandNum) == thousandNum){ return ("\(Int(thousandNum))k").replacingOccurrences(of: ".0", with: "") } return("\(thousandNum.roundTo(places: 1))k").replacingOccurrences(of: ".0", with: "") } if self > 1000000{ if(floor(millionNum) == millionNum){ return("\(Int(thousandNum))k").replacingOccurrences(of: ".0", with: "") } return ("\(millionNum.roundTo(places: 1))M").replacingOccurrences(of: ".0", with: "") } else{ if(floor(self) == self){ return ("\(Int(self))") } return ("\(self)") } } /// Returns rounded value for passed places /// /// - parameter places: Pass number of digit for rounded value off after decimal /// /// - returns: Returns rounded value with passed places func roundTo(places:Int) -> Double { let divisor = pow(10.0, Double(places)) return (self * divisor).rounded() / divisor } } 

在此处输入图像描述
在此处输入图像描述
在此处输入图像描述
在此处输入图像描述

对于swift 4.0。 它的工作完全正常,并根据@ user3483203回答

将Double值转换为String的函数

 func formatPoints(num: Double) ->String{ var thousandNum = num/1000 var millionNum = num/1000000 if num >= 1000 && num < 1000000{ if(floor(thousandNum) == thousandNum){ return("\(Int(thousandNum))k") } return("\(thousandNum.roundToPlaces(places: 1))k") } if num > 1000000{ if(floor(millionNum) == millionNum){ return("\(Int(thousandNum))k") } return ("\(millionNum.roundToPlaces(places: 1))M") } else{ if(floor(num) == num){ return ("\(Int(num))") } return ("\(num)") } } 

进行一次Double扩展

 extension Double { /// Rounds the double to decimal places value mutating func roundToPlaces(places:Int) -> Double { let divisor = pow(10.0, Double(places)) return Darwin.round(self * divisor) / divisor } } 

使用上述function

UILABEL.text = formatPoints(num:Double(310940)!)

输出:

在此处输入图像描述