我正在尝试从我的列表中获取一些元素的总和。 每个元素都有一个称为数量的 Int 属性。
我的元素:
class EmbeddedElement : EmbeddedRealmObject {
var totalPrice: Double = 0.0
var discount: Double = 0.0
var quantity: Int = 1
}
我正在尝试获取元素总价的总和。
myElementsList 具有独特的元素。
问题是,每当我尝试将 totalPrice 值与 $0.quantity 相乘时,它就不会生成。错误:
编译器无法在合理的时间内对该表达式进行类型检查;尝试将表达式分解成不同的子表达式
例如这 not 工作(当与 $0.quantity 相乘时):
Text("\((myElementsList.map({($0.totalPrice-($0.totalPrice*$0.discount/100))*$0.quantity}).reduce(0,+)), specifier: "%.2f") dollar ")
但是乘以简单的数字 5 或任何其他数字都可以:
Text("\((myElementsList.map({($0.totalPrice-($0.totalPrice*$0.discount/100))*5}).reduce(0,+)), specifier: "%.2f") dollar ")
为什么会这样?这是因为 $0.quantity 是一个 Int 值?我试过铸造但没有任何效果。有什么解决办法吗?
您在计算的第一部分乘以双精度,计算中的所有内容都应为双精度。如果您将 Int “初始化”为双精度数,它会起作用,例如。
双人间($0.数量)
有了这个,数学在操场上运行良好。最好在操作员周围留出空间,因为我在这上面有几个标志。
class EmbeddedElement {
var totalPrice: Double = 5.0
var discount: Double = 3.2
var quantity: Int = 1
}
let element = EmbeddedElement()
var array = Array(repeatElement(element, count: 500))
let sum = array.map {
($0.totalPrice - ($0.totalPrice*$0.discount / 100)) * Double($0.quantity)
}.reduce(0,+)
第二个计算中的静态 5 起作用,因为它知道计算是双精度的,结果将是双精度的,所以它有效地将 5 “初始化”为双精度。
在处理价格和货币时,您可能需要查看 Decimal 类型,正如您在我的简单示例中看到的那样,双精度数会导致小数位过长,并且需要四舍五入,这会导致很多值出现微小差异。
我猜你看到的错误是模糊的,因为它非常复杂,类型系统正在努力提供有意义的东西。
我认为问题中的代码大部分是正确的。我不能保证数学方程是正确的,但代码是正确的。这是解决问题的方法
获取您的初始代码
Text("\((myElementsList.map({($0.totalPrice-($0.totalPrice*$0.discount/100))*$0.quantity}).reduce(0,+)), specifier: "%.2f") dollar ")
让我们把它分解成小块以便检查,删除公式,留下文本格式代码
Text("\(( ), specifier: "%.2f") dollar ")
然后方程式
let y = myElementsList.map({($0.totalPrice-($0.totalPrice*$0.discount/100))*$0.quantity}).reduce(0,+))
啊——现在问题很明显了;如我的评论中所述,错误是将 double 乘以 Int。修正方程很容易!将 Int 转换为 Double,然后进行计算。
let y = myElementsList.map({($0.totalPrice-($0.totalPrice*$0.discount/100))*Double($0.quantity)}).reduce(0,+)
不太复杂!
然后将其插入到文本代码中
Text("\((y), specifier: "%.2f") dollar ")
它有效。
在 Hongtron 的回答和我的后续评论中查看关于使用 Doubles from currency 的评论。使用 Decimal128.