web-dev-qa-db-ja.com

Swiftで値の辞書配列を検索

私は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

これをどう進めるかについての支援に感謝します。例を探してみましたが、ここでやろうとしていることに当てはまるものをすぐに見つけます。

11
Adrian

ループ内では、辞書から「お気に入りの飲み物」エントリをフェッチして、配列に追加する必要があります。

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

注、if let drink =は、配列にそのようなエントリが存在しない可能性を防ぎます。存在しない場合は、nilが返され、ifはそれをチェックして、次の場合にのみエントリを追加します。それはnilではありません。

if let部分で、代わりにlet drink = character["favorite drink"]!、最後に感嘆符を付けます。 これを行わないでください。これはオプションの「強制アンラップ」と呼ばれ、ディクショナリから有効な値が返されない場合、プログラムはクラッシュします。

最初の例の動作は、飲み物がない場合は配列に追加しません。しかし、文字配列のエントリと飲み物配列のエントリの間に1対1の対応が期待されるため、これは適切ではない場合があります。

それが事実であり、おそらく空の文字列が必要な場合は、代わりにこれを行うことができます。

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

.mapは、charactersのすべてのエントリを実行し、この式の実行結果を新しい配列(次に返す)に配置することを意味します。

??は、左側からnilが返された場合は、右側の値に置き換えます。

15
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]
6
Aleksey G.

対気速度速度の答えは非常に包括的であり、機能するソリューションを提供します。同じ結果を得るよりコンパクトな方法は、Swift配列のfilterおよびmapメソッドを使用することです。

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"の要素の存在を確認します。このメソッドは、その条件を満たす辞書の配列を返します。

2番目のステップでは、mapメソッドを使用して各辞書を"favorite drink "キーに対応する値に変換します-辞書の検索では常にオプションが返されることを考慮して(欠落したキーを考慮に入れて)、フィルターがそのキーの値を持たないすべてのディクショナリをすでに除外しているため、強制アンラップ演算子!を適用して、オプション以外の文字列を返すことは安全です。

結合された結果は文字列の配列です-私の遊び場からコピーされました:

["Prune juice", "tea, Earl Grey, hot"]
6
Antonio

それはあなたを助けるかもしれません

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
Sachin Nikumbh
  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
      }
1