在Swift中搜索字典数组的值

时间:2015-01-28 22:13:27

标签: ios arrays xcode swift dictionary

我是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

对于如何在这方面取得进展,我将不胜感激。我已经挖掘了一些例子,但我很快找到一个适用于我在这里尝试做的事情。

6 个答案:

答案 0 :(得分:14)

在循环中,您需要获取最喜欢的饮料&#34;从字典中输入,并将其附加到数组:

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

注意,if let drink =防止阵列中没有此类条目的可能性 - 如果没有,则返回nilif为检查,只有在条目不是零的情况下才添加条目。

您有时可能会看到人们跳过if let部分,而只是写let drink = character["favorite drink"]!,最后带有感叹号。 不要这样做。这被称为&#34;强行展开&#34;可选,如果字典中没有返回有效值,程序将崩溃。

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

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

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

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

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

答案 1 :(得分:6)

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]

答案 2 :(得分: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&#34;相对应的值。 key - 考虑到字典查找总是返回一个可选项(以说明丢失的密钥),并且过滤器已经排除了没有该键值的所有字典,应用强制解包运算符是安全的!返回非可选字符串。

组合结果是一个字符串数组 - 从我的操场上复制:

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

答案 3 :(得分:2)

它可能对你有帮助

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)");

答案 4 :(得分:1)

  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
      }

答案 5 :(得分:-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;
        }

    }