【问题标题】:Search Array of Dictionaries for Value in Swift在 Swift 中搜索字典数组的值
【发布时间】:2015-03-28 00:19:27
【问题描述】:

我是 Swift 新手,正在上课学习 iOS 编程。我发现自己很难理解如何在字典数组中搜索字符串值并将字符串值转储到数组中。这是取自我的 Xcode 游乐场。

我试图弄清楚如何: 1) 搜索字典数组 2) 将搜索结果转储到一个数组(我已经创建)

这些是字符字典。

let worf = [
    "name": "Worf",
    "rank": "lieutenant",
    "information": "son of Mogh, slayer of Gowron",
    "favorite drink": "prune juice",
    "quote" : "Today is a good day to die."]

let picard = [
    "name": "Jean-Luc Picard",
    "rank": "captain",
    "information": "Captain of the USS Enterprise",
    "favorite drink": "tea, Earl Grey, hot"]

这是上面列出的字符字典的数组。

let characters = [worf, picard]

这是我正在尝试编写的函数。

func favoriteDrinksArrayForCharacters(characters:Array<Dictionary<String, String>>) -> Array<String> {
    // create an array of Strings to dump in favorite drink strings
    var favoriteDrinkArray = [String]()

    for character in characters {
        // look up favorite drink

        // add favorite drink to favoriteDrinkArray
    }

    return favoriteDrinkArray
}

let favoriteDrinks = favoriteDrinksArrayForCharacters(characters)

favoriteDrinks

我将不胜感激有关如何推进这方面的任何帮助。我已经挖掘了一些例子,但我很快就找到了一个适用于我在这里尝试做的事情。

【问题讨论】:

    标签: ios arrays xcode swift dictionary


    【解决方案1】:

    也许对你有帮助

    var customerNameDict = ["firstName":"karthi","LastName":"alagu","MiddleName":"prabhu"];
    var clientNameDict = ["firstName":"Selva","LastName":"kumar","MiddleName":"m"];
    var employeeNameDict = ["firstName":"karthi","LastName":"prabhu","MiddleName":"kp"];
    
    var attributeValue = "karthi";
    
    var arrNames:Array = [customerNameDict,clientNameDict,employeeNameDict];
    
    var namePredicate = NSPredicate(format: "firstName like %@",attributeValue);
    
    let filteredArray = arrNames.filter { namePredicate.evaluateWithObject($0) };
    println("names = ,\(filteredArray)");
    

    【讨论】:

      【解决方案2】:

      我有一个客户数组,每个客户都有姓名、电话号码和其他存根。所以我使用下面的代码在搜索栏中的字典数组中搜索电话号码

       for  index in self.customerArray
          {
              var string = index.valueForKey("phone")
              if let phoneNumber = index.valueForKey("phone") as? String {
                  string = phoneNumber
              }
              else
              {
                  string = ""
              }
              if string!.localizedCaseInsensitiveContainsString(searchText) {
                  filtered.addObject(index)
                  searchActive = true;
              }
      
          }
      

      【讨论】:

        【解决方案3】:
          Use the following code to search from NSArray of dictionaries whose keys are ID and Name.
        
              var txtVal:NSString
              let path = NSBundle.mainBundle().pathForResource(plistName, ofType: "plist")
              var list = NSArray(contentsOfFile: path!) as [[String:String]]
        
              var namePredicate = NSPredicate(format: "ID like %@",  String(forId));
              let filteredArray = list.filter { namePredicate!.evaluateWithObject($0) };
              if filteredArray.count != 0
              {
                  let value = filteredArray[0] as NSDictionary
                  txtVal = value.objectForKey("Name") as String
              }
        

        【讨论】:

          【解决方案4】:
          let drinks = characters.map({$0["favorite drink"]}) // [Optional("prune juice"), Optional("tea, Earl Grey, hot")]
          

          let drinks = characters.filter({$0["favorite drink"] != nil}).map({$0["favorite drink"]!}) // [prune juice, tea, Earl Grey, hot]
          

          【讨论】:

            【解决方案5】:

            Airspeed Velocity 的答案非常全面,并提供了一个可行的解决方案。实现相同结果的更紧凑的方法是使用 swift 数组的 filtermap 方法:

            func favoriteDrinksArrayForCharacters(characters:Array<Dictionary<String, String>>) -> Array<String> {
                // create an array of Strings to dump in favorite drink strings
                return characters.filter { $0["favorite drink"] != nil }.map { $0["favorite drink"]! }
            }
            

            过滤器接受一个返回布尔值的闭包,它表明一个元素是否必须被包含 - 在我们的例子中,它检查键 "favorite drink" 的元素是否存在。此方法返回满足该条件的字典数组。

            第二步使用map 方法将每个字典转换为与"favorite drink" 键对应的值 - 考虑到字典查找总是返回一个可选的(以考虑缺少键),并且filter 已经排除了所有没有该键值的字典,可以安全地应用强制展开运算符 ! 来返回非可选字符串。

            合并后的结果是一个字符串数组 - 从我的 Playground 复制而来:

            ["prune juice", "tea, Earl Grey, hot"]
            

            【讨论】:

            • 感谢您的回答!这个和空速速度都有效。我将研究您的代码,并希望在提高编码技能时使用类似的紧凑语法。感谢您的回答和时间!
            【解决方案6】:

            在循环内部,您需要从字典中获取“最喜欢的饮料”条目,并将其附加到数组中:

            for character in characters {
                if let drink = character["favorite drink"] {
                    favoriteDrinkArray.append(drink)
                }
            }
            

            注意,if let drink = 防止数组中没有这样的条目的可能性 - 如果没有,你会得到一个 nil 回来,if 正在检查它,只添加条目如果不为零。

            您有时可能会看到人们跳过if let 部分,而只是写let drink = character["favorite drink"]!,末尾带有感叹号。 不要这样做。这被称为“强制解包”一个可选项,如果字典没有返回有效值,您的程序将崩溃。

            第一个示例的行为是,如果没有饮料,则不要将其添加到数组中。但这可能不是您想要的,因为您可能期望字符数组中的条目和饮料数组中的条目之间存在一对一的对应关系。

            如果是这样,并且您可能想要一个空字符串,您可以这样做:

            func favoriteDrinksArrayForCharacters(characters: [[String:String]]) -> [String] {
                return characters.map { character in
                    character["favorite drink"] ?? ""
                }
            }
            

            .map 的意思是:遍历characters 中的每个条目,并将运行此表达式的结果放入一个新数组(然后返回)。

            ?? 表示:如果您从左侧取回 nil,请将其替换为右侧的值。

            【讨论】:

            • 感谢您的宝贵时间和回答!我很欣赏带有谨慎代码的简单解释(没有强制解包)和更详细的解释。非常感谢!
            猜你喜欢
            • 2016-03-11
            • 2022-11-20
            • 1970-01-01
            • 2018-04-14
            • 1970-01-01
            • 1970-01-01
            • 2017-02-03
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多