首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用iOS快速格式化来自JSON可编码/ API的数据

使用iOS快速格式化来自JSON可编码/ API的数据
EN

Stack Overflow用户
提问于 2022-07-07 08:48:36
回答 3查看 55关注 0票数 0

我有一些JSON,我想在使用之前重新格式化,最好是在初始化器中(或者扩展名?)

代码语言:javascript
运行
复制
[
{
 "name": "Diesel",
 "id": "1",
 "maj": "2022-07-06 18:28:29",
 "value": "2.81"
  },
{
 "name": "SP95",
 "id": "5",
 "maj": "2022-07-06 18:28:29",
 "value": "2.048"
  }
] 

我想确保“值”数据总是小数点3位。所以在上面的2.810,而不是2.81。

我看过CustomStringConvertible,理论上它看起来是可能的,但我还没有成功地构建一个工作版本。

主要从这里工作,https://www.swiftbysundell.com/articles/formatting-numbers-in-swift/

我的模特看起来是这样的:

代码语言:javascript
运行
复制
struct Price: Codable {
    let name: String
    let id, maj: String?
    var value: String?
    var isCheapest: Bool?
        
}

我知道我需要做一些基本的数字格式化,但是我不知道如何将它与CustomStringConvertible集成,或者这是否是正确的方法。任何帮助都很感激。

EN

回答 3

Stack Overflow用户

发布于 2022-07-07 09:25:20

使用扩展

代码语言:javascript
运行
复制
extension Metric: CustomStringConvertible {
    var description: String {
        let formatter = NumberFormatter()
        formatter.numberStyle = .decimal
        formatter.maximumFractionDigits = 3

        let number = NSNumber(value: value)
        let formattedValue = formatter.string(from: number)!
        return "\(name): \(formattedValue)"
    }
}
票数 1
EN

Stack Overflow用户

发布于 2022-07-07 09:32:17

我想你可以像下面这样使用它

字符串的扩展

代码语言:javascript
运行
复制
extension String {
    var doubleValue: Double? {
        get{
            Double(self)
        }
    }

    var formatedValue: String? {
        get{
            // YOU HAVE TO MAKE SURE THAT THE STRING IS CONVERTABLE TO `DOUBLE`
            String(format: "%.3f", self.doubleValue ?? 0.000)
        }
    }
}

用法:

代码语言:javascript
运行
复制
let price = Price(name: "Diesel", id: "1", maj: "2022-07-06 18:28:29", value: "2.81", isCheapest: false)
if let value = price.value?.formatedValue{
    print(value)
}
//Console Output - 2.810
票数 0
EN

Stack Overflow用户

发布于 2022-07-07 10:01:07

我将将String值替换为自定义类型,即下面示例中的Wrapped,并为其实现Codable,这对于底层字符串值应该是透明的。

还请注意数字格式化程序上的舍入模式,如果您想简单地剪切分数,那么.floor应该这样做。

代码语言:javascript
运行
复制
import Foundation

private let formatter: NumberFormatter = {
    let formatter = NumberFormatter()
    formatter.decimalSeparator = "."
    formatter.maximumFractionDigits = 3
    formatter.roundingMode = .floor
    return formatter
}()

struct Value: Codable {
    var wrapped: Wrapped
}

struct Wrapped: Codable {
    let source: NSNumber

    var doubleValue: Double {
        return source.doubleValue
    }

    init(_ doubleValue: Double) {
        source = NSNumber(value: doubleValue)
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        let stringValue = try container.decode(String.self)

        guard let numberObject = formatter.number(from: stringValue) else {
            throw DecodingError.dataCorrupted(
                DecodingError.Context(
                    codingPath: container.codingPath,
                    debugDescription: "Cannot parse NSNumber from String")
            )
        }

        source = numberObject
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()

        guard let stringValue = formatter.string(from: source) else {
            throw EncodingError.invalidValue(
                source,
                EncodingError.Context(
                    codingPath: container.codingPath,
                    debugDescription: "Cannot convert NSNumber to String"
                )
            )
        }

        try container.encode(stringValue)
    }

}

let value = Value(wrapped: Wrapped(11.234567899))
let data = try! JSONEncoder().encode(value)
let stringData = String(data: data, encoding: .utf8)!

// Prints: {"wrapped": "11.234"}
print("\(stringData)")


// Prints 11.234
let reverse = try JSONDecoder().decode(Value.self, from: data)
print("\(reverse.wrapped.source)")
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72894850

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档