在Swift中减少托管对象数组
问题描述:
我在确定用于减少Swift中自定义托管对象子类数组的语法时遇到了问题。我有一个被称为amount的属性的管理对象子类,它是一个NSNumber。如何使用reduce函数来获取受管理对象数组中每个项目的金额总和。这是我尝试过的,但是我得到一个错误,提示“无法找到成员'金额'”。在Swift中减少托管对象数组
let reduceSum=myArray.reduce(0) {$0 + $1.amount}
我已经看过这个example,但它并没有帮助,因为我得到了找不到成员的错误。
答
在发布之后,我尝试了一件事情,它工作。该错误消息是误导性的,让我觉得语法错了,但真正的问题是我需要将NSNumber转换为CGFloat。这里是什么工作:
let reduceSum=myArray.reduce(0) {$0 + CGFloat($1.amount)}
答
extension Array {
var sumInt: Int { return map { $0 as! Int }.reduce(0) { $0 + $1 } }
var sumUInt: UInt { return map { $0 as! UInt }.reduce(0) { $0 + $1 } }
var sumUInt8: UInt8 { return map { $0 as! UInt8 }.reduce(0) { $0 + $1 } }
var sumUInt16: UInt16 { return map { $0 as! UInt16 }.reduce(0) { $0 + $1 } }
var sumUInt32: UInt32 { return map { $0 as! UInt32 }.reduce(0) { $0 + $1 } }
var sumUInt64: UInt64 { return map { $0 as! UInt64 }.reduce(0) { $0 + $1 } }
var sumDouble: Double { return map { $0 as! Double }.reduce(0) { $0 + $1 } }
var sumFloat: Float { return map { $0 as! Float }.reduce(0) { $0 + $1 } }
var sumCGFloat: CGFloat { return map { $0 as! CGFloat }.reduce(0) { $0 + $1 } }
var sum: T {
if !isEmpty {
if first is Int { return sumInt as! T }
if first is UInt { return sumUInt as! T }
if first is UInt8 { return sumUInt8 as! T }
if first is UInt16 { return sumUInt16 as! T }
if first is UInt32 { return sumUInt32 as! T }
if first is UInt64 { return sumUInt64 as! T }
if first is Double { return sumDouble as! T }
if first is Float { return sumFloat as! T }
if first is CGFloat{ return sumCGFloat as! T }
}
return 0 as! T
}
}
用法:
let inputArrayInt:[Int]=[1,2,3]
let sumInt = inputArrayInt.sum // 6
let inputArrayUInt:[UInt]=[1,2,3]
let sumUInt = inputArrayUInt.sum // 6
let inputArrayUInt8:[UInt8]=[1,2,3]
let sumUInt8 = inputArrayUInt8.sum // 6
let inputArrayUInt16:[UInt16]=[1,2,3]
let sumUInt16 = inputArrayUInt16.sum // 6
let inputArrayUInt32:[UInt32]=[1,2,3]
let sumUInt32 = inputArrayUInt32.sum // 6
let inputArrayUInt64:[UInt64]=[1,2,3]
let sumUInt64 = inputArrayUInt64.sum // 6
let inputArrayDouble:[Double]=[1.0,2.0,3.0]
let sumDouble = inputArrayDouble.sum // 6.0
let inputArrayFloat:[Float]=[1.0,2.0,3.0]
let sumFloat = inputArrayFloat.sum // 6.0
let inputArrayCGFloat:[CGFloat]=[1.0,2.0,3.0]
let sumCGFloat = inputArrayCGFloat.sum // 6.0
let inputArray = [1.3,2,3]
let sum = inputArray.sum // 6.3
为什么该行并不需要'$ 0.amount'? – 2016-04-14 00:19:03
如果你看看我在我的问题中引用的例子,那可以比我更好地解释它。在该链接中“在reduce代码中,第一个闭包参数($ 0)是从零开始的运行总数,第二个参数($ 1)引用people数组中的Person对象。” – 2016-04-16 01:21:37
但是,为什么我们需要将其转换为CGFloat?它有效,但为什么? – user1007522 2016-06-16 07:20:07