gpt4 book ai didi

swift - 在 Swift 中如何编写一个函数来转换 [String :[Int]] to [String:Int]

转载 作者:搜寻专家 更新时间:2023-11-01 06:57:40 25 4
gpt4 key购买 nike

我得到了一个应用列表及其评级:

let appRatings = [
"Calendar Pro": [1, 5, 5, 4, 2, 1, 5, 4],
"The Messenger": [5, 4, 2, 5, 4, 1, 1, 2],
"Socialise": [2, 1, 2, 2, 1, 2, 4, 2]
]

我想编写一个将 appRating 作为输入并返回他们的姓名和平均评分的函数,就像这样。

["Calendar Pro": 3,
"The Messenger": 3,
"Socialise": 2]

有谁知道如何使用 func 中的闭包来实现这样一种方法,它将(name 和 [rating])作为输入和输出(name 和 avgRating)?

这就是我目前所拥有的。

func calculate( appName: String, ratings : [Int]) -> (String, Double ) {
let avg = ratings.reduce(0,+)/ratings.count

return (appName, Double(avg))
}

最佳答案

从根本上说,您要实现的是一组值到另一组值之间的映射。字典有一个功能,Dictionary.mapValues(_:) ,专门用于仅映射值(将它们保存在相同的键下)。

let appRatings = [
"Calendar Pro": [1, 5, 5, 4, 2, 1, 5, 4],
"The Messenger": [5, 4, 2, 5, 4, 1, 1, 2],
"Socialise": [2, 1, 2, 2, 1, 2, 4, 2]
]

let avgAppRatings = appRatings.mapValues { allRatings in
return computeAverage(of: allRatings) // Dummy function we'll implement later
}

所以现在,问题是弄清楚如何对数组中的所有数字进行平均。幸运的是,这非常简单:

  1. 我们需要对所有评分求和

    • 我们可以使用 reduce 表达式轻松实现这一点。 StWe 将通过简单地将它们添加到累加器中来减少所有数字,累加器将从 0 开始

      allRatings.reduce(0, { accumulator, rating in accumulator + rate })

      从这里,我们可以注意到闭包 { accumulator, rating in accumulator + rate } 的类型为 (Int, Int) -> Int,并且只是添加数字在一起。好吧,这正是 + 所做的!我们可以直接使用它:

      allRatings.reduce(0, +)
  2. 我们需要将评分除以评分数

    • 这里有个问题。为了使平均值有用,它不能被截断为纯粹的 Int。 因此我们需要将总和和计数都转换为 Double首先。
  3. 您需要防止出现空数组,其计数将为 0,从而导致 Double.infinity

把它们放在一起,我们得到:

let appRatings = [
"Calendar Pro": [1, 5, 5, 4, 2, 1, 5, 4],
"The Messenger": [5, 4, 2, 5, 4, 1, 1, 2],
"Socialise": [2, 1, 2, 2, 1, 2, 4, 2]
]

let avgAppRatings = appRatings.mapValues { allRatings in
if allRatings.isEmpty { return nil }
return Double(allRatings.reduce(0, +)) / Double(allRatings.count)
}

添加一些 pretty-print 逻辑:

extension Dictionary {
var toDictionaryLiteralString: String {
return """
[
\t\(self.map { k, v in "\(k): \(v)" }.joined(separator: "\n\t"))
]
"""
}
}

... 繁荣:

print(avgAppRatings.toDictionaryLiteralString)
/* prints:
[
Socialise: 2.0
The Messenger: 3.0
Calendar Pro: 3.375
]
*/

对您尝试的评论

您对为什么您的尝试无效有一些疑问:

func calculate( appName: String, ratings : [Int]) -> (String: Int ) {
var avg = ratings.reduce(0,$0+$1)/ratings.count
return appName: sum/avg
}
  1. $0+$1 不在闭包内 ({ }),因为它需要在闭包内。
  2. appName: sum/avg 不是有效的 Swift。
  3. 变量 sum 不存在。
  4. avg 是一个 var 变量,即使它从未发生变化。它应该是一个 let 常量。
  5. 您正在进行整数除法,它不支持小数。首先,您需要将求和和计数转换为浮点类型,例如 Double

固定版本可能如下所示:

func calculateAverage(of numbers: [Int]) -> Double {
let sum = Double(ratings.reduce(0, +))
let count = Double(numbers.count)
return sum / count
}

要创建一个处理整个字典的函数,并结合我上面的解决方案,您可以编写如下函数:

func calculateAveragesRatings(of appRatings: [String: [Int]]) -> [String: Double?] {
return appRatings.mapValues { allRatings in
if allRatings.isEmpty { return nil }
return Double(allRatings.reduce(0, +)) / Double(allRatings.count)
}
}

关于swift - 在 Swift 中如何编写一个函数来转换 [String :[Int]] to [String:Int],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52522767/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com