如何在Swift中为字典找到平均值?

3

我有一个字典,比方说

let gamePrices = [
"Shooter": [40,60,80],
"RTS": [15,35,55]
"RPG": [5,40,70]
]
avgGamePrices(dictionary: [String: Int]) -> Double {
var total = 0;
for int in dictionary {
total += int
} 

(我认为在这里使用int是错误的)我不明白如何获取每个流派的平均价格和总平均价格(所有9个值的平均数)。我甚至不知道如何在for循环中“提及”字典的ints或strings。对于默认数组,我会使用

for number in numbers {
total += number
}
let numbersTotal = Int(numbers.count);
let average = total/numbersTotal;
return (Double(average);

你能否将RTS中的Shooter值减少? - Larme
很抱歉,我写了自己的新代码。但首先我需要完成我的任务,而且整数和字符串的数量是相同的(就像我的示例中一样)。 - Billy Milligan
2个回答

3

要得到所有价格的平均值,你需要先从字典中获取所有价格,然后再计算平均值。这与计算平均数不同:

let gamePrices = [
    "Shooter": [40,60,80],
    "RTS":     [15,35,55],
    "RPG":     [5,40,70]]

let allPrices = gamePrices.flatMap(\.value)
let sum = allPrices.reduce(.zero, +)
let average = Double(sum) / Double(allPrices.count)  //  44.44444444444444

为了使每个流派获得最高价格:
let maxPrices: [(genre: String, maxPrice: Int)] = gamePrices.map { ($0, $1.max() ?? .zero)}  // [(genre "Shooter", maxPrice 80), (genre "RTS", maxPrice 55), (genre "RPG", maxPrice 70)]

for (genre, max) in maxPrices {
    print("Genre:", genre, "Max price:", max)
}

谢谢,maxPrices确实可行,但它在控制台中打印了很多“垃圾”,有没有更简单的方法,不用map,??和.zero? - Billy Milligan
如果你确定价格数组不为空,可以强制解包它的值,或者将结果保持为可选。 - Leo Dabus
好的,那你能解释一下 "gamePrices.map { ($0, $1.max() ?? .zero)}" 这段代码是什么意思以及它是如何工作的吗?我从未使用过这样的代码,包含 ??、.zero 和 $ 符号,所以我不太明白这是什么。 - Billy Milligan
好的,$0 是元组的第一个元素,$1 是第二个元素。字典是一种集合,其元素被定义为“public typealias Element = (key: Key, value: Value)”键值对。因此,我正在映射每个键值对。$0 是键,而 $1 是值(它是一个集合)。max 是集合的一个方法,它从中返回最大值,如果集合为空,则返回 nil。 - Leo Dabus
请注意,它也可以写成 gamePrices.map { ($0.key, $0.value.max() ?? .zero)},这对于初学者来说更容易理解,并且在 Swift 3 之前曾经是唯一的实现方式(据我所知)。 - Leo Dabus
1
@JoakimDanielson 我同意这不是问题的一部分,但我只需要不到30秒就可以将其添加到帖子中。考虑到我已经有了代码,我决定也将其发布出来。至少原帖作者尝试解决了原始问题。 - Leo Dabus

1
如果您要搜索总平均值,则应像这样操作:
func avgGamePrices(dictionary: [String: [Int]]) -> Double {
var total = 0;
var countElem = 0

for obj in dictionary {
    countElem += obj.value.count
    for v in obj.value {
        total += v
    }
}

return Double(total / countElem)

}

调用:

avgGamePrices(dictionary: gamePrices)

否则,对于每个键:
func avg(for key: String, dictionary: [String: [Int]]) -> Double {
var total = 0;
let countElem = (dictionary[key] ?? []).count

for v in (dictionary[key] ?? []) {
    total += v
}

return Double(total / countElem)

}

你可以通过以下方式进行调用(将字典中的单个键作为参数传递):

avg(for: "RTS", dictionary: gamePrices)

应该可以,谢谢。但是在这种情况下,我如何计算整数的平均值和总平均值? - Billy Milligan
我真的不太明白如何调用这个函数...print(avgGamePrices(dictionary : gamePrices));这似乎不对。 - Billy Milligan
谢谢,它正在工作,尽管我已经用for循环和print(在那里我做了这样的计算“total / Double(price.count)”)而没有使用func完成了它。我要做的最后一件事是获取每种类型的最高价格。如果不难,请告诉我错误在哪里?我认为可以用一行代码完成。 让maxPrice = gamePrices.max {a,b in a.value < b.value} print(maxPrice) 但是,它说“二进制运算符“<”不能应用于两个'[Int]'操作数。”听起来很奇怪... - Billy Milligan
1
请注意,先进行整数除法,然后再将其转换为Double是有点毫无意义的,因为精度已经丢失了。所以最好在执行除法之前先将值转换为Double。 - Joakim Danielson
你应该使用基于字典键的下标和默认值,它返回一个非可选值dictionary[key, default: []] - Leo Dabus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接