【问题标题】:Add values from multiple dictionaries in firebase into an Int将 firebase 中多个字典的值添加到 Int 中
【发布时间】:2019-08-22 22:57:26
【问题描述】:

我正在使用 firebase 来存储我的应用中每个视频的观看次数。我想要的是从一个用户的所有视频中收集所有视图并显示视图总数。但是,我在获取数据并将所有字典值一起放入 Int/String 时遇到问题!

到目前为止,我已经尝试了许多不同的解决方案,但我仍然在字典的数组/值中得到所有不同的值,而不是把所有东西都添加到一个值中

这是我获取特定用户的所有视频视图的代码,到目前为止没有任何问题。当我打印“intConvert”时,我得到了不同行中的所有视图。


      let ref = Database.database().reference().child("videoviews").child(stringUid)
    ref.observe(.value, with: { (snapshot) in
        if let dictionary = snapshot.value as? [String: AnyObject]{

            let numbOfViews = dictionary["views"] as! String
            let intConvert = Int(numbOfViews)!
            let ArrayViews = [intConvert]

这是我的数据库结构:

   **videoviews**
        -Lb52VxrEqdSRGljJdP7
                          views: "25"

        -Lb53ARq_lOHEbTruW8s
                          views: "273"

        -Lb53A_cEyX3CYc4mKYn
                          views: "38"

编辑:如果我打印(字典),来自“if let dictionary = snapshot.value as? [String: Anyobject] 的字典看起来像这样:

      ["views": 642]
      ["views": 660]
      ["views": 628]
      ["views": 630]
      ["views": 615]
      ["views": 3]
      ["views": 0]
      ["views": 2]
      ["views": 1]

编辑:(我很困惑,忘记添加手镯,抱歉。) 当我这样做时,我“打印(dictionary.values)控制台看起来像这样(来自不同字典的键值):

  [642]
  [660]
  [628]
  [630]
  [615]
   [3]
   [0]
   [2]
   [1]

然后我试着把它放在一个这样的循环中:


       var bLoader = 0.0
            for hejArray in 0...ArreyViews.count-1{
                bLoader += Double(Arrej[hejArray])
            }

但是当我打印“bLoader”时,我仍然会在不同的行中获得每个视频的所有视图,而不是收集在一个值中。

那么我需要做什么将 Firebase 中不同字典中的所有值放在一个变量中?

感谢我能得到的所有帮助,我可以想象这应该不会太难,但我错过了一些东西。

EDIT /// 终于找到问题了。我传入的“StringUid”具有不同数量的值,因此如果用户的视频数量为 9,则整个函数将被调用 9 次。最终工作的解决方案如下所示:

全局数组声明:

              var myArray = [String]()

函数内部:

       if let dictionary = snapshot.value as? [String: AnyObject]{
            let numbOfViews = dictionary["views"] as! String
            let intConvert = Int(numbOfViews)!
            self.myArray.append(numbOfViews)
            let intArray = self.myArray.map { Int($0)!} 
            let total = intArray.reduce(0, +)
            self.totalViewsShower2.text = String(total)

提前谢谢你!

【问题讨论】:

    标签: arrays swift firebase dictionary firebase-realtime-database


    【解决方案1】:

    更新

    如果您可以像这样直接打印字典中的值,那么解决方案可能就像

    一样简单
    let total = dictionary.values.reduce(0, +)
    

    或者如果值是字符串,则需要将它们转换为 Int

    let total = dictionary.values.reduce(0) {sum, value -> Int in return sum + (Int(value) ?? 0)}
    

    另一方面,如果它们的值是字符串但定义为 Any,则需要额外的演员表

    let total2 = dictionary2.values.reduce(0) {sum, value -> Int in
        if let str = value as? String {
            return sum + (Int(str) ?? 0)
        }
        return 0
    }    
    

    我不确定你的字典包含什么,但我假设是这样的

    let dictionary: [String: Any] = ["views": ["1", "2", "3"]]
    

    然后您可以将“views”键的值转换为字符串数组,然后在该数组上使用reduce 来获取总和

    let array = dictionary["views"] as! [String]
    let total = array.reduce(0) {sum, value -> Int in return sum + (Int(value) ?? 0)}
    

    【讨论】:

    • 您好 Joakim,感谢您的回答。我试过了,但是当我像这样声明数组时,应用程序崩溃了。我用控制台的外观和数据库结构更新了我的答案:)
    • 再次感谢您的回答!我很笨拙,当我打印 (dictionary.values) 时忘记在我的帖子中添加 [ ] 。但是,你是对的,它们被定义为 Anyobject 并且需要转换为 String -> Int 如果我理解正确的话。我试过你的答案,当我打印 total2 时,我得到的值是 642、660... 但仍然在不同的行中。似乎每个字典都在自行转换,而不是组合成一个值!
    • 如果我意识到该函数被调用的次数与 StringUid 的数量一样多,那么您的代码将从一开始就可以工作。感谢您的帮助!
    【解决方案2】:

    根据您的数据库结构,看起来像这样

    {
        "videoviews": {
            "Lb52VxrEqdSRGljJdP7": {
                "views": "25"
            },
            "Lb53ARq_lOHEbTruW8s": {
                "views": "273"
            },
            "Lb53A_cEyX3CYc4mKYn": {
                "views": "38"
            }
        }
    }
    
     let ref = Database.database().reference().child("videoviews").child(stringUid)
        ref.observe(.value, with: { (snapshot) in
    
            if let dictionary = snapshot.value as? [String: AnyObject] {
                let viewsArray = dictionary.values
                                .compactMap { $0 as? [String: String] }
                                .compactMap { Int($0["views"] ?? "") }
    
                let totalViews = viewsArray.reduce(0, +)
            }
    }) 
    

    【讨论】:

    • 这是compactMap的文档,供您参考:- developer.apple.com/documentation/swift/sequence/…
    • 感谢您的回答。到目前为止,我对 compactMap 有点陌生,所以我可能做错了什么。当我输入您的代码时,编译器告诉我将第二个紧凑映射中的“”更改为 Int 以让我运行代码。然后,当我打印 totalViews 时,我得到的值为 0 并位于不同的行中。如果我正确理解firebase,它必须按这个顺序。任何对象 -> 字符串 -> 整数。也许上面的一些代码更改可以工作! :)
    • @Wurzel 我稍微更新了代码,而不是直接将类型转换为[String: Int],现在改为[String: String]。我希望这应该根据提供的信息起作用。
    • 您好!谢谢,我试过你编辑的代码。当我打印 totalViews 时,我仍然在不同的行中得到 0。我用控制台中的 print(dictionary) 和 print(dictionary.values) 的外观更新了我的帖子。当我们已经查看值而不是键时,它是否必须与查找 ["views"] 相关联?
    • 编辑:我终于找到了解决方案(问题是函数被调用的次数与 StringUids 的数量一样多。这可能很明显,但我是初学者(:)。不过谢谢感谢您对 compactMap 的帮助和新知识!
    猜你喜欢
    • 2023-03-31
    • 1970-01-01
    • 2022-01-23
    • 2017-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多