我想在映射时修改roomTotal键的值。请参考以下代码:
struct TransactionInfoModel: Codable {
var currencyCode: String
var total: Double
var roomCurrencyCode: String
var exchangeRate: Double
var roomTotal: Double {
get {
let y = (self.roomTotal*100).rounded()/100
return y
}
}
}
最初,roomTotal键具有来自服务器的值,如“427.3000000002”但我希望在映射时存储值“427.3”。上面的代码不起作用。
寻找一些解决问题的建议。
有关如何舍入this answer值并返回将保留舍入的Double
值的示例,请参阅Decimal
,而不会尝试在二进制浮点表示中表示十进制值时产生任何工件。然后,您可以像这样获得舍入的Decimal
值:
let roomTotal = 427.3000000002
let value = roomTotal.roundedDecimal(to: 2)
如果你想用指定的小数位数显示它(以及为用户的当前语言环境本地化字符串),你可以使用NumberFormatter
:
let formatter = NumberFormatter()
formatter.maximumFractionDigits = 2
formatter.minimumFractionDigits = 2
if let string = formatter.string(for: value) {
print(string)
}
现在,如果你想让JSONDecoder
为你做这个转换,你可以,但我可能倾向于让struct
准确地表示返回的内容,避免任何错综复杂的init(from:)
实现,但可能包含一个计算属性来返回值你想要的格式,例如:
struct TransactionInfoModel: Codable {
var currencyCode: String
var total: Double
var roomCurrencyCode: String
var exchangeRate: Double
var roomTotal: Double
var roundedRoomTotal: Decimal {
return roomTotal.roundedDecimal(to: 2)
}
}
如果你需要在解码时围绕roomTotal
,你可以写一个init(from:)
来做到这一点:
struct TransactionInfoModel: Codable {
var currencyCode: String
var total: Double
var roomCurrencyCode: String
var exchangeRate: Double
var roomTotal: Decimal
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
currencyCode = try values.decode(String.self, forKey: .currencyCode)
total = try values.decode(Double.self, forKey: .total)
roomCurrencyCode = try values.decode(String.self, forKey: .roomCurrencyCode)
exchangeRate = try values.decode(Double.self, forKey: .exchangeRate)
roomTotal = try values.decode(Double.self, forKey: .roomTotal).roundedDecimal(to: 2)
}
}
或者,您可以省略init(from:)
,但在解析后手动舍入:
struct TransactionInfoModel: Codable {
var currencyCode: String
var total: Double
var roomCurrencyCode: String
var exchangeRate: Double
var roomTotal: Decimal
}
和:
var object = try! JSONDecoder().decode(TransactionInfoModel.self, from: data)
var rounded = Decimal()
NSDecimalRound(&rounded, &object.roomTotal, 2, .plain)
object.roomTotal = rounded