对 Swift 中嵌套自定义对象的值求和
Sum the Values of Nested Custom Objects in Swift
我正在尝试将在 Swift 中的某些自定义对象中找到的值相加。我有以下代码在 Playground 中工作:
//Custom Object
class EntryPack: NSObject{
var date: String!
var duration: Double!
var customValues:[CustomValuePack] = [] //Nested array of objects declared below
}
//Another object to nest in the above
class CustomValuePack: NSObject{
var name:String!
var value: Double!
}
//Instantiate nested objects
let cv1 = CustomValuePack()
cv1.name = "Day"
cv1.value = 1.2
let cv2 = CustomValuePack()
cv2.name = "Day"
cv2.value = 1.3
let cv3 = CustomValuePack()
cv2.name = "Night"
cv2.value = 2.2
//Instantiate parent objects
let entry1 = EntryPack()
entry1.date = "bingo"
entry1.duration = 1.1
entry1.customValues = [cv1, cv2]
let entry2 = EntryPack()
entry2.date = "bingo"
entry2.duration = 2.2
let entry3 = EntryPack()
entry3.date = "dang"
entry3.duration = 3.0
//Throw it all together into an array
var package = [entry1, entry2, entry3]
//Predicate for some filtering
let predicate = NSPredicate(format:"date = %@", "bingo")
let results = (package as NSArray).filteredArrayUsingPredicate(predicate) as! [EntryPack]
//Sum all the parent object durations
let sum = results.reduce(0.0) { [=11=] + .duration }
print(sum) // = 3.3
但现在我想为每个 CustomValuePack
添加 value
,其中 name
是 "Day"
。
我不知道如何对嵌套的对象数组进行类似的归约。我试过这样的东西,但它会产生语法错误:
let sum2 = results.reduce(0.0) { [=12=].customValues + .customValues.value } //Error
如何对嵌套对象数组中的值求和? 我最终也想应用 NSPredicate 来按 name = Day
进行过滤,但我还没那么远。
给定entries
定义如下
let entries = [entry1, entry2, entry3]
您可以提取名称 == "Day" 的 CustomValues 并用此代码对值字段求和
let sum = entries
.flatMap { [=11=].customValues }
.filter { [=11=].name == "Day" }
.map { [=11=].value }
.reduce(0, combine: +)
改进
您正在使用 Swift,但由于某种原因,您的代码中仍有很多 Objective-C。
这就是我重构您的代码的方式
struct EntryPack {
let date: String
let duration: Double
let customValues:[CustomValuePack]
}
struct CustomValuePack {
let name:String
let value: Double
}
let cv1 = CustomValuePack(name: "Day", value: 1.2)
let cv2 = CustomValuePack(name: "Day", value: 1.3)
let cv3 = CustomValuePack(name: "Night", value: 2.2)
let entry1 = EntryPack(date: "bingo", duration: 1.1, customValues: [cv1, cv2])
let entry2 = EntryPack(date: "bingo", duration: 2.2, customValues: [])
let entry3 = EntryPack(date: "dang", duration: 3.0, customValues: [])
Please note that now EntryPack
and CustomValuePack
are structs which are value types.
我正在尝试将在 Swift 中的某些自定义对象中找到的值相加。我有以下代码在 Playground 中工作:
//Custom Object
class EntryPack: NSObject{
var date: String!
var duration: Double!
var customValues:[CustomValuePack] = [] //Nested array of objects declared below
}
//Another object to nest in the above
class CustomValuePack: NSObject{
var name:String!
var value: Double!
}
//Instantiate nested objects
let cv1 = CustomValuePack()
cv1.name = "Day"
cv1.value = 1.2
let cv2 = CustomValuePack()
cv2.name = "Day"
cv2.value = 1.3
let cv3 = CustomValuePack()
cv2.name = "Night"
cv2.value = 2.2
//Instantiate parent objects
let entry1 = EntryPack()
entry1.date = "bingo"
entry1.duration = 1.1
entry1.customValues = [cv1, cv2]
let entry2 = EntryPack()
entry2.date = "bingo"
entry2.duration = 2.2
let entry3 = EntryPack()
entry3.date = "dang"
entry3.duration = 3.0
//Throw it all together into an array
var package = [entry1, entry2, entry3]
//Predicate for some filtering
let predicate = NSPredicate(format:"date = %@", "bingo")
let results = (package as NSArray).filteredArrayUsingPredicate(predicate) as! [EntryPack]
//Sum all the parent object durations
let sum = results.reduce(0.0) { [=11=] + .duration }
print(sum) // = 3.3
但现在我想为每个 CustomValuePack
添加 value
,其中 name
是 "Day"
。
我不知道如何对嵌套的对象数组进行类似的归约。我试过这样的东西,但它会产生语法错误:
let sum2 = results.reduce(0.0) { [=12=].customValues + .customValues.value } //Error
如何对嵌套对象数组中的值求和? 我最终也想应用 NSPredicate 来按 name = Day
进行过滤,但我还没那么远。
给定entries
定义如下
let entries = [entry1, entry2, entry3]
您可以提取名称 == "Day" 的 CustomValues 并用此代码对值字段求和
let sum = entries
.flatMap { [=11=].customValues }
.filter { [=11=].name == "Day" }
.map { [=11=].value }
.reduce(0, combine: +)
改进
您正在使用 Swift,但由于某种原因,您的代码中仍有很多 Objective-C。
这就是我重构您的代码的方式
struct EntryPack {
let date: String
let duration: Double
let customValues:[CustomValuePack]
}
struct CustomValuePack {
let name:String
let value: Double
}
let cv1 = CustomValuePack(name: "Day", value: 1.2)
let cv2 = CustomValuePack(name: "Day", value: 1.3)
let cv3 = CustomValuePack(name: "Night", value: 2.2)
let entry1 = EntryPack(date: "bingo", duration: 1.1, customValues: [cv1, cv2])
let entry2 = EntryPack(date: "bingo", duration: 2.2, customValues: [])
let entry3 = EntryPack(date: "dang", duration: 3.0, customValues: [])
Please note that now
EntryPack
andCustomValuePack
are structs which are value types.