I read in a random text file I've created
hard toffee 10
hard toffee 20
...
chewy gum 40
soft marshmallow 20
hard toffee 30
soft marshmallow 40
I create an array of sweets/candy objects and store it like this:
var candyArray = [
Candy(consistency: "hard", type: "toffee", cost: 10),
...
Candy(consistency: "soft", type: "marshmellow", cost: 40)]
Each object can be accessed through its properties:
print(\(candyArray[0].type))
// prints toffeee
I'd like to iterate through the array and if the consistency is hard, I want to += the cost to a variable used to store the sum of cost for hard candy. I want to do the same with the other consistencies and then compare them to see which has the greatest cost when summed up. Any help at all would be greatly appreciated. Here's what I have so far:
struct Candy {
var consistency: String
var type: String
var cost: Double
init(consistency: String, type: String, cost: Double) {
self.consistency = consistency
self.type = type
self.cost = cost
}
}
var candyArray = [
Candy(consistency: "hard", type: "toffee", cost: 40),
Candy(consistency: "hard", type: "toffee", cost: 5),
Candy(consistency: "hard", type: "toffee", cost: 5),
Candy(consistency: "soft", type: "marshmallow", cost: 30),
Candy(consistency: "soft", type: "marshmallow", cost: 35),
Candy(consistency: "chewy", type: "gum", cost: 35)
]
print("\(candyArray[0].type)")
var x = 0
var largestValue = 0.0
var tempValue = 0.0
var currentConsistency = candyArray[x].consistency
var mostExpensiveConsistency = ""
while (x < candyArray.count){
if (currentConsistency == candyArray[x].consistency) {
tempValue += candyArray[x].cost
} else if (currentConsistency != candyArray[x].consistency) {
tempValue = 0
currentConsistency = candyArray[x].consistency
}
if (tempValue > largestValue) {
largestValue = tempValue
mostExpensiveConsistency = currentConsistency
}
x+=1
}
print(" largest value: \(largestValue) and most expensive consistency: \(mostExpensiveConsistency)")
The code doesn't work when the consistency type isn't ordered like in the above text file I mentioned. I was thinking of creating a 2d array or a dictionary and storing the consistency as a key and sum as a value for each consistency so that if the consistency appears again I can add it to the sum that was previously stored in an array/dictionary. I hope I made sense. I'm just wondering if there's a faster way of doing this.
答案 0 :(得分:3)
Swift 4的字典初始化程序可以为您完成大部分工作。
例如:
let costs = Dictionary(candyArray.map{($0.consistency,$0.cost)}, uniquingKeysWith:+)
let highest = costs.max{$0.value < $1.value} // ("soft",65)
let hardCost = costs["hard"] // 50
答案 1 :(得分:1)
Swift在集合上提供了一些很好的函数来简化这些类型的任务:declare let window;
,map
和filter
。
例如,你可以通过写下来获得硬糖的总成本:
reduce
执行以下操作:
let hardCost = candyArray.filter{ $0.consistency == "hard" }.map{ $0.cost }.reduce(0, +)
:返回一个只包含与指定条件匹配的项目的数组(filter
)
consistency == "hard"
:返回map
结果
filter
:通过对输入数组的所有元素执行操作(在本例中为reduce
)来聚合单个结果
您可以针对每种类型的一致性执行相同的过程,或者编写一个扩展方法,jut采用您想要的一致性名称,例如。
+
然后像这样使用它来获得每个一致性的值:
extension Array where Element == Candy {
func costOf(consistency: String) {
candyArray.filter{ $0.consistency == consistency }.map{ $0.cost }.reduce(0, +)
}
}
答案 2 :(得分:1)
let candies = [
Candy(consistency: "b", type: "b", cost: 1.5),
Candy(consistency: "a", type: "b", cost: 1.0),
Candy(consistency: "a", type: "b", cost: 2.0),
Candy(consistency: "c", type: "b", cost: 3.0),
Candy(consistency: "b", type: "b", cost: 1.0),
Candy(consistency: "c", type: "b", cost: 2.0),
]
// 1
var costSummary = [String: Double]()
// 2
candies.forEach {
costSummary[$0.consistency] = (costSummary[$0.consistency] ?? 0.0) + $0.cost
}
// 3
let mostExpensive = costSummary.reduce(("", 0.0)) { result, next in
return result.1 > next.1 ? result : next
}
答案 3 :(得分:1)
这是一个很好的管道,可以帮助您实现目标
x = ActiveSupport::MessageEncryptor.new('12345678901234567890123456789012').encrypt_and_sign('foo')
=> "bXJmRUczdjVXRFdLTitUcmkvRnk1UT09LS0vb2ZYdDRybGdWbmNXMUI1VDNnQzVBPT0=--13232bbe31d966f7d1df3aaa6fcc1cdc9eea60a1"
ActiveSupport::MessageEncryptor.new('12345678901234567890123456789012').decrypt_and_verify(x)
=> "foo"
结果是可选的,这将指示您尝试处理空的糖果阵列(不太可能但可能的情况),因此您也可以处理那个。
顺便说一句,我无法注意到您经常使用let maxCost = Dictionary(grouping: candyArray, by: { $0.consistency }) // group candies by consistency
.map { ($0.key, $0.value.reduce(0) { $0 + $1.cost }) } // compute the total cost for each consistency
.sorted { $0.1 > $1.1 } // sort descending by price
.first // take the first result
,您可能希望将所有var
转换为只读var
(let
为了更好的可预测性和更好的性能(编译器可以在知道变量是常量的情况下进行优化)。以下结构声明与您的相同(编译器免费提供的成员初始化程序):
struct Candy {
let consistency: String
let type: String
let cost: Double
}