包含自定义类的数组总和(Swift)
Posted
技术标签:
【中文标题】包含自定义类的数组总和(Swift)【英文标题】:Sum of Array containing custom class (Swift) 【发布时间】:2019-07-09 20:44:49 【问题描述】:我正在寻找一种方法来获取包含在数组中的类的值的总和。我的设置如下:
class CustomClass
var value: Int?
init(value: Int)
self.value = value
let object1 = CustomClass(value: 2)
let object2 = CustomClass(value: 4)
let object3 = CustomClass(value: 8)
let array: [CustomClass] = [object1, object2, object3]
我目前的解决方案如下:
var sumArray = [Int]()
for object in array
sumArray.append(object.value!)
let sum = sumArray.reduce(0, +)
问题在于,对于具有许多其他值的类,它变得非常复杂,有人知道更好的解决方案吗?
【问题讨论】:
当您说“非常复杂的类具有许多其他值”时,这是否意味着您也在尝试将不同类型的类的值包含到求和运算中? 是的,确实如此。事实上,我的课程包含 Int 和 Date 类型,但日期类型不应该被“合并”.. @AndreasSchultz 到目前为止,我没有看到任何复杂的东西。您必须以某种方式将对象转换为数字(您已经在这样做了,尽管.map
会是更好的解决方案),然后将数字相加。
【参考方案1】:
您可以将您的自定义类数组压缩映射为整数数组,然后将该数组缩减为其总和。喜欢,
let sum = array.lazy.compactMap $0.value
.reduce(0, +)
【讨论】:
使用尾随闭包,可以简化为.reduce(0, +)
我会在那里放一个lazy
,以跳过compactMap
导致的中间数组分配
@Alexander 我想知道该怎么做。是不是像lazy var sum = array.compactMap $0.value .reduce(0, +)
??
不不,lazy
属性使表达式在第一次请求时计算。它仍然涉及中间数组。相反,您使用数组的 lazy
计算属性,它返回一个惰性视图,该视图跟踪您要执行的操作,在需要结果之前不实际执行它们。 array.lazy.compactMap $0.value .reduce(0, +)
【参考方案2】:
您可以在array
上使用单个reduce
。
let sumOfValues = array.reduce($0 += ($1.value ?? 0))
【讨论】:
没有必要为此使用reduce into。reduce(0) $0 + ($1.value ?? 0)
@LeoDabus 你是对的,没有需要使用reduce(into:,_:)
,但我也没有看到使用reduce(_:,_:)
的任何优势
有但我不适合向您解释。在 Swift 4 中实现 reduce(into:)
之前,人们有时需要将结果声明为变量,以便能够在闭包内对其进行更改。如果您不需要更改它,只需使用简单的 reduce 并返回总和 result
加上元素。
Resuming 如果你使用普通的 reduce 方法,闭包内没有变量,只有常量【参考方案3】:
我将为您的类或结构创建一个包含值的协议。并将其声明更改为非可选。
protocol Valueable
var value: Int get
那么你需要让你的类符合那个协议:
class CustomClass: Valueable
let value: Int
init(value: Int)
self.value = value
现在您可以使用只读实例属性扩展收集协议,以返回数组中所有元素的总和。
extension Collection where Element: Valueable
var sum: Int
return reduce(0) $0 + $1.value
let object1 = CustomClass(value: 2)
let object2 = CustomClass(value: 4)
let object3 = CustomClass(value: 8)
let objects = [object1, object2, object3]
let sum = objects.sum // 14
编辑/更新:
另一种选择是扩展序列并添加一个generic sum method,它接受其属性符合AdditiveArithmetic
的关键路径
或将关联类型添加到符合 AdditiveArithmetic 的协议中:
protocol Valueable
associatedtype Value: AdditiveArithmetic
var value: Value get
extension Collection where Element: Valueable
var sum: Element.Value reduce(.zero) $0 + $1.value
class CustomClass: Valueable
let value: Decimal
init(value: Decimal)
self.value = value
用法:
let object1 = CustomClass(value: 123.4567)
let object2 = CustomClass(value: 12.34567)
let object3 = CustomClass(value: 1.234567)
let objects = [object1, object2, object3]
let sum = objects.sum // 137.036937
【讨论】:
这太复杂了,抱歉。 @user3069232 这取决于你的编程水平。这是非常基本的协议用法,这是 Swift 成功的主要原因(面向协议的语言) @user3069232 另一种选择是扩展序列并添加一个generic sum method,它接受其属性符合AdditiveArithmetic
的关键路径
@user3069232 检查我上次的编辑。那是它开始变得复杂的时候。以上是关于包含自定义类的数组总和(Swift)的主要内容,如果未能解决你的问题,请参考以下文章