Skip to content

Instantly share code, notes, and snippets.

@eldaroid
Last active July 17, 2024 19:34
Show Gist options
  • Save eldaroid/af2bddcb4f5d658211fcfc4b2ae4242f to your computer and use it in GitHub Desktop.
Save eldaroid/af2bddcb4f5d658211fcfc4b2ae4242f to your computer and use it in GitHub Desktop.
Преобразование чисел в удобочитаемый формат, добавляя соответствующие постфиксы для больших чисел (например, 123 тысяч, 5 миллионов, 8 миллиардов и т.д.).
public extension Double {
func humanFormatted(
groupingSeparator: String = " ",
roundingMode: NumberFormatter.RoundingMode = .halfEven,
fractionDigits: Int = 1,
threshold: Double = 9_999
) -> (stringValue: String, postfix: String?) {
let dividerNames: [String?] = [nil, "тыс.", "млн", "млрд", "трлн", "квадрлн"]
var index = 0
var humanValue = self
while abs(humanValue) > threshold {
humanValue /= 1_000
index += 1
}
let formatter = NumberFormatter()
let number = NSNumber(value: humanValue)
formatter.roundingMode = roundingMode
formatter.minimumFractionDigits = 0
formatter.maximumFractionDigits = fractionDigits
formatter.groupingSeparator = groupingSeparator
formatter.numberStyle = .decimal
let stringValue = formatter.string(from: number)?.replacingOccurrences(of: ".", with: ",") ?? ""
return (
stringValue: stringValue,
postfix: index < dividerNames.count ? dividerNames[index] : nil
)
}
}
@eldaroid
Copy link
Author

Usage:

let number1: Double = 1234567844239048
let number1Formatted = number1.humanFormatted(groupingSeparator: "()")
print("Number 1: \(number1Formatted.stringValue) \(number1Formatted.postfix ?? "")")
// Number 1: 1()234,6 трлн

let number2: Double = 19949
let number2Formatted = number2.humanFormatted()
print("Number 2: \(number2Formatted.stringValue) \(number2Formatted.postfix ?? "")")

let number3: Double = 19950
let number3Formatted = number3.humanFormatted()
print("Number 3: \(number3Formatted.stringValue) \(number3Formatted.postfix ?? "")")

let number4: Double = 19950
let number4Formatted = number4.humanFormatted(roundingMode: .down)
print("Number 4: \(number4Formatted.stringValue) \(number4Formatted.postfix ?? "")")

let number5: Double = 999999999999
let number5Formatted = number5.humanFormatted()
print("Number 5: \(number5Formatted.stringValue) \(number5Formatted.postfix ?? "")")

@eldaroid
Copy link
Author

eldaroid commented Jul 17, 2024

7 видов NumberFormatter.RoundingMode:

Пример для понимания:

import Foundation

let numberFormatter = NumberFormatter()
let number = -1.45
let number2 = 1.45
numberFormatter.maximumFractionDigits = 1

// Округляем от нуля
numberFormatter.roundingMode = .up

print("up")
print(numberFormatter.string(for: number))  // -1.5
print(numberFormatter.string(for: number2)) // 1.5

// Округляем в сторону нуля
numberFormatter.roundingMode = .down

print("\ndown")
print(numberFormatter.string(for: number))  // -1.4
print(numberFormatter.string(for: number2)) // 1.4

// Округление в сторону положительной бесконечности
numberFormatter.roundingMode = .ceiling

print("\nceiling")
print(numberFormatter.string(for: number))  // -1.4
print(numberFormatter.string(for: number2)) // 1.5

// Округляем в сторону минус бесконечности
numberFormatter.roundingMode = .floor

print("\nfloor")
print(numberFormatter.string(for: number))  // -1.5
print(numberFormatter.string(for: number2)) // 1.4

// Округлите в сторону ближайшего целого числа или если оно равноудалено, то от нуля
numberFormatter.roundingMode = .halfUp

print("\nhalfUp")
print(numberFormatter.string(for: number))  // -1.5
print(numberFormatter.string(for: number2)) // 1.5

// Округлите в сторону ближайшего целого числа или если оно равноудалено, то к нулю
numberFormatter.roundingMode = .halfDown

print("\nhalfDown")
print(numberFormatter.string(for: number))  // -1.4
print(numberFormatter.string(for: number2)) // 1.4

// Округлите в сторону ближайшего целого числа или если оно равноудалено, то в сторону четного числа
numberFormatter.roundingMode = .halfEven

print("\nhalfEven")
print(numberFormatter.string(for: number))  // -1.4
print(numberFormatter.string(for: number2)) // 1.4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment