2017-02-20 69 views
-1

我確實在確定SwiftyJson中返回的特定值時遇到了問題;希望有人能幫我解釋一下。在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 
} 

然後創建一個函數來處理的水平狀態,

最後將其與View Controller中的JSON響應進行比較並推進d級如果匹配

  // 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() 
     }) 
    } 
+1

我對於幾件事情有點不清楚:首先 - 爲什麼你要爲你的'labels'數組的每個條目添加一個逗號?其次,它看起來像從'JSON'設置'labels'爲每個'description' ...所以如果您需要將這些值與用戶輸入的某個單詞進行比較,會爲您篩選工作嗎? 'let matches = labels.filter {$ 0.contains(user_entered_word)}' – Pierce

+0

只有在返回多個JSON響應時纔會使用逗號;如果我預先定義了一個單一的期望單詞,顯然不需要這樣做。如果我可以使用「過濾器」,那麼肯定,正如我在其他例子中看到的,但我不知道如何設置在我的代碼中:/一分鐘,我覺得我真的明白Json,下一分鐘我是解析它完全困惑。 @Pierce – pythlang

+0

我在下面爲你添加了一個答案。希望它有幫助 – Pierce

回答

0

第一件事 - 我真的不明白爲什麼你要在每個描述的末尾附加一個逗號。我真的沒必要。你對分離數組中的元素感到困惑嗎?因爲實際的String不需要,只有在您手動寫出數組的元素(即let array = ["a", "b", "c"])時才需要。

因此,然後說你設置這個labels數組,這是一個String s數組的屬性。

var labels: Array<String> = [] 

一旦你經歷了,並從JSON附加的所有description值,然後你可以操縱它。

if numLabels > 0 { 

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

} 

現在你可以創建一個能夠返回基於一些用戶輸入的字String秒的濾波陣列的方法:

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

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

} 

現在你可以用上面的方法來處理某種用戶進入,就像說你有從UITextField名爲textField文:

// 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語句。這真的取決於你以及你想如何設計你的遊戲。

+0

@pythlang - 哦好吧,我明白你在說什麼了。爲了保持正常工作,我只會建議在打算打印時做類似的事情。 – Pierce

+0

輝煌,我會嘗試一下。在每個描述的末尾添加一個逗號對我來說很合適,因爲我只是將結果返回爲這樣一個長句子:「發現的標籤:stem,table,hand,apple」,所以如果我要省略附加的逗號看起來很糟糕,即:「標籤發現:幹手錶蘋果手機」。如果使用逗號附加是多餘的,並且無論如何都是通過「.count」完成的,那麼我想我總是可以刪除它。將不會有用戶輸入,相反,這些預定義的單詞在遊戲應該如何進展方面將被硬編碼。那看起來怎麼樣? @Pierce – pythlang

+0

@pythlang - 它看起來完全一樣,你可以用你預定義的單詞替換我使用textField中的文本的部分:'let matches = findMatches(「your_predefined_word」)' – Pierce