【问题标题】:Matching an exact key in SwiftyJson匹配 SwiftyJson 中的精确键
【发布时间】:2017-02-20 19:43:36
【问题描述】:

我真的很难确定 SwiftyJson 中返回的特定值;希望有人能帮我解释一下。

我想查看预先确定的单词“apple”是否与从 JSON 响应中收到的任何单词匹配。

如果匹配,则会显示一条消息,用户要么选择进入下一个级别,要么返回主屏幕。

如果没有匹配,则会显示一条消息,用户必须继续播放或取消播放。

我想对游戏不同级别的多个单词执行此操作。

第一级:将“apple”匹配到任何接收到的 JSON 响应。

第二级:将“计算机”匹配到任何接收到的 JSON 响应。

第三级:将“电话”或“电话”或“iPhone”或“Android”或上述任何或所有内容与收到的任何 JSON 响应匹配。

因此,基本上,我可以获得所有 JSON 响应,但我很难找出如何设置以确定是否返回了特定的、预定义的 JSON 响应。

我用另一个帖子到处找了几个星期,但无济于事:(

JSON 响应

    {
  "responses" : [
    {
      "labelAnnotations" : [
        {
          "mid" : "\/m\/01m2v",
          "score" : 0.9245476,
          "description" : "computer keyboard"
        },
        {
          "mid" : "\/m\/01c648",
          "score" : 0.7945268,
          "description" : "laptop"
        },
        {
          "mid" : "\/m\/01mfj",
          "score" : 0.74227184,
          "description" : "computer hardware"
        },
        {
          "mid" : "\/m\/0541p",
          "score" : 0.7062791,
          "description" : "multimedia"
        },
        {
          "mid" : "\/m\/07c1v",
          "score" : 0.7039645,
          "description" : "technology"
        },
        {
          "mid" : "\/m\/03gq5hm",
          "score" : 0.69323385,
          "description" : "font"
        },
        {
          "mid" : "\/m\/0bs7_0t",
          "score" : 0.6724673,
          "description" : "electronic device"
        },
        {
          "mid" : "\/m\/01vdm0",
          "score" : 0.66489816,
          "description" : "electronic keyboard"
        },
        {
          "mid" : "\/m\/0121tl",
          "score" : 0.60392517,
          "description" : "electronic instrument"
        },
        {
          "mid" : "\/m\/0h8n5_7",
          "score" : 0.5834592,
          "description" : "laptop replacement keyboard"
        }
      ]
    }
  ]
}

显示所有 JSON 响应的代码

 // Use SwiftyJSON to parse results
        let json = JSON(data: dataToParse)
        let errorObj: JSON = json["error"]

 // Parse the response
            print(json)
            let responses: JSON = json["responses"][0]

                // Get label annotations
            let labelAnnotations: JSON = responses["labelAnnotations"]
            let numLabels: Int = labelAnnotations.count
            var labels: Array<String> = []
            if numLabels > 0 {
                var labelResultsText:String = "Labels found: "
                for index in 0..<numLabels {
                    let label = labelAnnotations[index]["description"].stringValue
                    labels.append(label)
                }
                for label in labels {
                    // if it's not the last item add a comma
                    if labels[labels.count - 1] != label {
                        labelResultsText += "\(label), "
                    } else {
                        labelResultsText += "\(label)"
                    }
                }
                self.labelResults.text = labelResultsText
            } else {
                self.labelResults.text = "No labels found"
            }

编辑

我显然无法回答我自己的问题,我会发布一个编辑,因为我认为这是一个更好的解决方案,但 @pierce 的一个词相当不错,不是很多;它只是不适用于游戏设置应用程序。

所以,我创建了一个新的 NSObject,创建了一个

static var _words: [[String]] = [

["apple", "computer", "beer"]]

然后

func checkAnnotations(annotations: [Annotation]) -> Bool {
    var isMatched = false

    let searchWords = self.words
    for searchWord in searchWords {
        for annotation in annotations {
            if searchWord == annotation.descriptionString {
                isMatched = true
                break
            }
        }

        if isMatched {
            break
        }
    }

    return isMatched
}

然后创建了一个函数来处理关卡状态,

最后将其与视图控制器中的 JSON 响应和高级级别(如果匹配)进行比较

            // Get JSON key value
            let labelAnnotations = responses["labelAnnotations"].arrayValue
            let annotationObjects: [Annotation] = labelAnnotations.flatMap({ annotationDictionary in
                if let mid = annotationDictionary["mid"].string,
                let score = annotationDictionary["score"].double,
                    let description = annotationDictionary["description"].string {
                    let annotation = Annotation(mid: mid, score: score, descriptionString: description)
                    return annotation
                }

                return nil
            })

            //print(annotationObjects)

            let searchString = LevelState.shared.words[0]
            print("Level \(LevelState.shared.level), looking for: \(searchString)")

            var isMatched = LevelState.shared.checkAnnotations(annotations: annotationObjects)
            if isMatched {
                LevelState.shared.advance()
            }

            let alertTitle = isMatched ? "Congrats! You got \(searchString)" : "Keep looking for \(searchString)"

            //let translationResult = "Translated: \(levelDescription) to \(translatedText)"

            let alertController = UIAlertController(title: alertTitle, message: nil, preferredStyle: .alert)
            alertController.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
            self.present(alertController, animated: true, completion: nil)

            }

        self.prepareForNewLevel()
        })
    }

【问题讨论】:

  • 我对几件事有点不清楚:首先 - 你为什么要在 labels 数组的每个条目中添加一个逗号?其次,您似乎将labels 设置为JSON 中的每个description ...因此,如果您需要将这些值与用户输入的某些单词进行比较,过滤器会为您工作吗? let matches = labels.filter { $0.contains(user_entered_word) }
  • 只有在返回多个 JSON 响应时才使用逗号;如果我预先定义了一个想要的单词,那显然是没有必要的。如果我可以使用“过滤器”,那么可以确定,正如我在其他示例中看到的那样,但我不确定如何在我的代码中进行设置:/ 一分钟我觉得我真的理解 Json,下一分钟我完全被解析弄糊涂了。 @皮尔斯
  • 我在下面为您添加了答案。希望对你有帮助
  • 我的回答有问题吗?你为什么不接受?我只是好奇
  • 阅读我上面帖子中的编辑。这还不错,但我认为我的解决方案更全面。我无法发布答案@Pierce

标签: ios json swift swifty-json


【解决方案1】:

第一件事 - 我真的不明白你为什么要在每个描述的末尾附加一个逗号。我真的觉得那是不必要的。您是否对分隔数组中的元素感到困惑?因为实际的 Strings 不需要这样做,所以只有当您手动写出数组的元素时(即 let array = ["a", "b", "c"])。

那么假设你为这个labels数组设置了一个属性,它是一个Strings的数组。

var labels: Array<String> = []

完成并附加来自JSON 的所有description 值后,您就可以对其进行操作了。

if numLabels > 0 {

    for index in 0..<numLabels {
        let label = labelAnnotations[index]["description"].stringValue
        labels.append(label)
    }

}

现在您可以创建一个方法,该方法将根据某些用户输入的单词返回过滤后的 Strings 数组:

func findMatches(_ userEntry: String) -> [String] {

    return labels.filter { $0.contains(userEntry) }

}

现在您可以使用上述方法来处理某种用户输入,例如说您有来自名为 textFieldUITextField 的文本:

// Return the filtered matches based on the textField text (unless nil)
let matches = findMatches(textField.text ?? "")

// Print the number of matches, and also show the matches
print("Found \(matches.count) matches to user input\r\(matches)")

现在,如果你有 labels 并持有 ["a", "aa", "ba", "b", "c", "apple"],并运行上面的代码,其中 userEntry 只是字母“a”,你会在控制台窗口中看到这个打印输出:

Found 4 matches to user input
["a", "aa", "ba", "apple"]

编辑 - 您可以使用上面的 findMatches 方法来尝试使用预先确定的单词进行匹配。我不确定你到底想做什么,但有几种不同的方法。首先,假设您有一个要检查的预定单词数组:

let words = ["word", "verb", "noun", "adverb"]

然后你可以遍历它并检查每一个

for word in words {

    let matches = findMatches(word)
    if matches.count > 0 {
        print("Found \(matches.count) matches to \(word)\r\(matches)")
    } else {
        // Do whatever you want when there are no matches
        print("No matches found")
    }

}

如果你只想检查一个特定的词,并有一个特定的响应,你可以设置这样的方法:

func checkWord(word: String, noMatchResponse: String) {

    let matches = findMatches(word)
    if matches.count > 0 {
        print("Found \(matches.count) matches to \(word)\r\(matches)")
    } else {
        // Do whatever with the no match response
        print(noMatchResponse)
    }

}

有很多方法可以实现这一点。您还可以使用switch 语句,然后对每个预先确定的单词使用不同的case 语句。这完全取决于您以及您希望如何设计游戏。

【讨论】:

  • @pythlang - 哦,好吧,我明白你在说什么。为了保持正常工作,我只建议您在计划打印时做类似的事情。
  • 太棒了,我会试试这个。在每个描述的末尾添加一个逗号对我有用,因为我只返回一个长句中的结果,如下所示:“找到的标签:茎、表、手、苹果”,所以如果我要省略附加的逗号,则列表看起来很糟糕,即:“发现标签:茎表手苹果”。如果附加逗号是多余的并且无论如何都会由“.count”完成,那么我想我总是可以删除它。不会有用户输入,而是这些预定义的单词将由我自己根据游戏的进度进行硬编码。那看起来怎么样? @皮尔斯
  • @pythlang - 看起来完全一样,你可以用你的预定义单词替换我使用 textField 中的文本的部分:let matches = findMatches("your_predefined_word")
  • 谢谢,我会尽快测试,如果有任何问题,我会回复;如果没有,我会接受你的回答。再次感谢。 @皮尔斯
  • func findMatches@Pierce 下运行let matches = findMatches("your_predefined_word") 时出现“使用未解析的标识符‘标签’”的问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-01
  • 2014-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多