我有一些JSON,我想在使用之前重新格式化,最好是在初始化器中(或者扩展名?)
[
{
"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/
我的模特看起来是这样的:
struct Price: Codable {
let name: String
let id, maj: String?
var value: String?
var isCheapest: Bool?
}
我知道我需要做一些基本的数字格式化,但是我不知道如何将它与CustomStringConvertible集成,或者这是否是正确的方法。任何帮助都很感激。
发布于 2022-07-07 09:25:20
使用扩展
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)"
}
}
发布于 2022-07-07 09:32:17
我想你可以像下面这样使用它
字符串的扩展
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)
}
}
}
用法:
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
发布于 2022-07-07 10:01:07
我将将String
值替换为自定义类型,即下面示例中的Wrapped
,并为其实现Codable
,这对于底层字符串值应该是透明的。
还请注意数字格式化程序上的舍入模式,如果您想简单地剪切分数,那么.floor
应该这样做。
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)")
https://stackoverflow.com/questions/72894850
复制相似问题