Свіфт - Як видалити десятковий знак з поплавця, якщо десятковий дорівнює 0?


88

Я відображаю відстань з одним десятковим знаком, і я хотів би видалити цей десятковий знак, якщо він дорівнює 0 (наприклад: 1200,0 км), як я міг зробити це швидко? Я відображаю цей номер так:

let distanceFloat: Float = (currentUser.distance! as NSString).floatValue
distanceLabel.text = String(format: "%.1f", distanceFloat) + "Km"

Відповіді:


137

Свіфт 3/4:

var distanceFloat1: Float = 5.0
var distanceFloat2: Float = 5.540
var distanceFloat3: Float = 5.03

extension Float {
    var clean: String {
       return self.truncatingRemainder(dividingBy: 1) == 0 ? String(format: "%.0f", self) : String(self)
    }
}

print("Value \(distanceFloat1.clean)") // 5
print("Value \(distanceFloat2.clean)") // 5.54
print("Value \(distanceFloat3.clean)") // 5.03

Свіфт 2 (оригінальна відповідь)

let distanceFloat: Float = (currentUser.distance! as NSString).floatValue
distanceLabel.text = String(format: distanceFloat == floor(distanceFloat) ? “%.0f" : "%.1f", distanceFloat) + "Km"

Або як розширення:

extension Float {
    var clean: String {
        return self % 1 == 0 ? String(format: "%.0f", self) : String(self)
    }
}

Я додав цей рядок раніше, distanceFloat = floor(distanceFloat * 10) / 10і тоді він спрацював чудово, дякую :)
Калі Аней

1
Для Double, extension Double {var clean: String {return self% 1 == 0? Рядок (формат: "% .0d", самостійно): Рядок (самостійно)}}
Abo3atef

3
Це не спрацює, якщо плаваюче значення приблизно 3.01.
chengsam

А як щодо від’ємних чисел?
Happiehappie

Для цього номера 123456738.0 це не працює, перетворене число має значення 123456736
Анірудха Махале

116

Використовуйте NSNumberFormatter:

let formatter = NumberFormatter()
formatter.minimumFractionDigits = 0
formatter.maximumFractionDigits = 2

// Avoid not getting a zero on numbers lower than 1
// Eg: .5, .67, etc...
formatter.numberStyle = .decimal

let nums = [3.0, 5.1, 7.21, 9.311, 600.0, 0.5677, 0.6988]

for num in nums {
    print(formatter.string(from: num as NSNumber) ?? "n/a")
}

Повернення:

3

5.1

7.21

9.31

600

0,57

0,7


2
ідеально! Це має бути зверху
GoodSp33d

6
для Свіфта 3: let formatter = NumberFormatter() formatter.minimumFractionDigits = 0 formatter.maximumFractionDigits = 1 statLabel.text = formatter.string(from: value as NSNumber) ?? "n/a"
alexxjk

1
Як щодо 0,3000, я намагаюся отримати це .3; Я задав його стильformatter.numberStyle = .decimal
stan liu

@stanliu правильний, якщо не додати число, .decimalстилі цифри нижче 1 відображатимуться без нуля. Наприклад: .5, .78 та ін ... Редагування відповіді зараз.
HotFudge, неділя,

Я вважаю, що саме це яблуко має намір вирішити таку проблему.
DragonCherry

55

extension це потужний спосіб це зробити.

Розширення :

Код для Swift 2 (не Swift 3 або новішої версії):

extension Float {
    var cleanValue: String {
        return self % 1 == 0 ? String(format: "%.0f", self) : String(self)
    }
}

Використання :

var sampleValue: Float = 3.234
print(sampleValue.cleanValue)

3.234

sampleValue = 3.0
print(sampleValue.cleanValue)

3

sampleValue = 3
print(sampleValue.cleanValue)

3


Зразок файлу Playground тут .


1
Але 3.230000 -> 3.230000 ... як щодо "-> 3.23"?
CHiP-love-NY

1
@ CHiP-love-NY, я вас не зрозумів.
Ашок,

1
Я вважаю, що він вважає, що ваше розширення не видаляє кінцеві нулі, але це робить. Рядок (3.230000) = "3.23"
jeffjv

34

Оновлення прийнятої відповіді для swift 3 :

extension Float
{
    var cleanValue: String
    {
        return self.truncatingRemainder(dividingBy: 1) == 0 ? String(format: "%.0f", self) : String(self)
    }
}

використання було б просто:

let someValue: Float = 3.0

print(someValue.cleanValue) //prints 3

Не працює, коли ви ставите тобто. 14.000005, він перетворюється на 14.0
Vetuka

@ sc13 Так, це дивно, але це відбувається, якщо ви натискаєте його на 14.00000005, тоді сам поплавок повертає 14 без 'cleanValue'. Думайте, це пов’язано з тим, як швидко справляється Float. Збираюся подивитися, чи можу я виправити цю помилку.
Крістофер Ларсен

2
Я отримую правильний результат для 14.000005, тому коментар @ sc13 здається застарілим або неправильним.
Cœur,

10

Щоб відформатувати його до рядка, дотримуйтесь цього шаблону

let aFloat: Float = 1.123

let aString: String = String(format: "%.0f", aFloat) // "1"
let aString: String = String(format: "%.1f", aFloat) // "1.1"
let aString: String = String(format: "%.2f", aFloat) // "1.12"
let aString: String = String(format: "%.3f", aFloat) // "1.123"

Щоб передати його на Int, дотримуйтесь цієї схеми

let aInt: Int = Int(aFloat) // "1"

Коли ви використовуєте String(format:ініціалізатор, Swift автоматично округляє останню цифру, якщо потрібно, виходячи з наступного числа.


Це не спрацює, якщо значення 1,678
Саурав Нагпал,

@SauravNagpal Це буде працювати :)
Baig

9

Ви можете використовувати розширення, як уже згадувалося, але це рішення трохи коротше:

extension Float {
    var shortValue: String {
        return String(format: "%g", self)
    }
}

Приклад використання:

var sample: Float = 3.234
print(sample.shortValue)

1
Не вдасться 0.00000001. Див. Документацію% g на pubs.opengroup.org/onlinepubs/009695399/functions/printf.html : " Використовуваний стиль залежить від перетвореного значення; стиль e (або E) використовуватиметься лише в тому випадку, якщо показник ступеня, отриманий в результаті такого перетворення менше -4 або більше або дорівнює точності. "
Cœur,

ідеально. Дякую
PhillipJacobs

7

У Swift 4 спробуйте це.

    extension CGFloat{
        var cleanValue: String{
            //return String(format: 1 == floor(self) ? "%.0f" : "%.2f", self)
            return self.truncatingRemainder(dividingBy: 1) == 0 ? String(format: "%.0f", self) : String(format: "%.2f", self)//
        }
    }

// Як використовувати - якщо після точки (.) Ви вводите більше двох символів, він автоматично обрізає останній символ і відображає лише два символи після точки.

let strValue = "32.12"
print(\(CGFloat(strValue).cleanValue)

Не буде обрізати нуль від значення 1.1: результат буде "1.10".
Cœur

@ Cœur він використовується для відображення двох значень після точки (.). якщо ви хочете відобразити лише одне значення, тоді використовується "return self.truncatingRemainder (splitingBy: 1) == 0? String (format:"% .0f ", self): String (format:"% .1f ", self) / / "
Джейдіп,

Я знаю ... Я просто описував, чим ваш код відрізняється від поведінки інших відповідей.
Cèur,

4

NSNumberFormatter - ваш друг

let distanceFloat: Float = (currentUser.distance! as NSString).floatValue
let numberFormatter = NSNumberFormatter()
numberFormatter.positiveFormat = "###0.##"
let distance = numberFormatter.stringFromNumber(NSNumber(float: distanceFloat))!
distanceLabel.text = distance + " Km"

4

Форматування з максимальним числом цифр, без кінцевих нулів

Цей сценарій хороший, коли бажана спеціальна точність виводу. Це рішення здається приблизно таким же швидким, як рішення NumberFormatter + NSNumber від MirekE , але однією перевагою може бути те, що ми уникаємо тут NSObject.

extension Double {
    func string(maximumFractionDigits: Int = 2) -> String {
        let s = String(format: "%.\(maximumFractionDigits)f", self)
        var offset = -maximumFractionDigits - 1
        for i in stride(from: 0, to: -maximumFractionDigits, by: -1) {
            if s[s.index(s.endIndex, offsetBy: i - 1)] != "0" {
                offset = i
                break
            }
        }
        return String(s[..<s.index(s.endIndex, offsetBy: offset)])
    }
}

(працює також із extension Floatтипом лише для macOS Float80) , але не

Використання: myNumericValue.string(maximumFractionDigits: 2)абоmyNumericValue.string()

Вихідні дані для maximumFractionDigits: 2:

1,0 → "1"
0,12 → "0,12"
0,012 → "0,01"
0,0012 → "0"
0,00012 → "0"


4

Swift 5 для Double - це те саме, що відповідь @ Frankie для float

var dec: Double = 1.0
dec.clean // 1

для продовження

extension Double {
    var clean: String {
       return self.truncatingRemainder(dividingBy: 1) == 0 ? String(format: "%.0f", self) : String(self)
    }

}

3

Ось повний код.

let numberA: Float = 123.456
let numberB: Float = 789.000

func displayNumber(number: Float) {
    if number - Float(Int(number)) == 0 {
        println("\(Int(number))")
    } else {
        println("\(number)")
    }
}

displayNumber(numberA) // console output: 123.456
displayNumber(numberB) // console output: 789

Ось найважливіший поглиблений рядок.

func displayNumber(number: Float) {
  1. Виділяє десяткові цифри з поплавком Int(number).
  2. Повертає позбавлене число назад до плаваючого для виконання операції Float(Int(number)).
  3. Отримує десяткове значення за допомогою number - Float(Int(number))
  4. Перевіряє десяткове число порожнє за допомогою if number - Float(Int(number)) == 0

Зміст операторів if та else не потребує пояснення.


У вашому випадку ви хотіли б зробити функцію повернення, Stringа не println(result)do return result. Сподіваюся, це допоможе!
Fine Man


2

Це також може бути корисним.

extension Float {
    func cleanValue() -> String {
        let intValue = Int(self)
        if self == 0 {return "0"}
        if self / Float (intValue) == 1 { return "\(intValue)" }
        return "\(self)"
    }
}

Використання:

let number:Float = 45.23230000
number.cleanValue()

-1

Можливо, stringByReplacingOccurrencesOfStringмогли б вам допомогти :)

let aFloat: Float = 1.000

let aString: String = String(format: "%.1f", aFloat) // "1.0"

let wantedString: String = aString.stringByReplacingOccurrencesOfString(".0", withString: "") // "1"

Це порушить значення, наприклад 1,05 -> 15
Starceaker

@Starceaker Ні, 1.05виконати String(format: "%.1f", aFloat)першим буде 1.0, працює. якщо 1.05виконати String(format: "%.2f", aFloat)буде 1.05, і чим це слід робитиstringByReplacingOccurrencesOfString(".00"...)
Лев

Правильно, я зосередився на останньому рядку. Я думав, ви запропонували кілька рішень, але насправді ваші лінії пов’язані. Моє ліжко.
Starceaker

це нічого :)
Лев
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.