Swiftで辞書を反復する


221

XcodeがSwiftプログラミング言語ガイドのこの実験に私を与えているという答えに少し混乱しています:

// Use a for-in to iterate through a dictionary (experiment)

let interestingNumbers = [
    "Prime": [2, 3, 5, 7, 11, 13],
    "Fibonacci": [1, 1, 2, 3, 5, 8],
    "Square": [1, 4, 9, 16, 25]
]
var largest = 0
for (kind, numbers) in interestingNumbers {
    for number in numbers {
        if number > largest {
            largest = number
        }
    }
}
largest

辞書を横切るときに、最大数が変数に設定されることを理解していますlargest。ただし、largest各テストに応じて、Xcodeが5倍、1倍、または3倍に設定されているのはなぜかと混乱しています。

コードを見ると、「Prime」だけで6回設定する必要があることがわかります(2、3、5、7、11、13)。次に、「フィボナッチ」の数値はすべてスキップされます。これらはすべて、現在「プライム」から13に設定されている最大値よりも小さいためです。次に、それを16に設定し、最後に「Square」で25に設定して、合計で8倍にする必要があります。

私は完全に明白な何かを見逃していますか?

回答:


355

Swift(およびその他の言語)の辞書は順序付けされていません。辞書を反復処理する場合、順序が初期化順序と一致する保証はありません。この例では、Swiftは「Square」キーを他のキーより先に処理します。これを確認するには、ループに印刷ステートメントを追加します。25はSquareの5番目の要素なので、Squareの5つの要素に対して最大が5回設定され、25のままになります。

let interestingNumbers = [
    "Prime": [2, 3, 5, 7, 11, 13],
    "Fibonacci": [1, 1, 2, 3, 5, 8],
    "Square": [1, 4, 9, 16, 25]
]
var largest = 0
for (kind, numbers) in interestingNumbers {
    println("kind: \(kind)")
    for number in numbers {
        if number > largest {
            largest = number
        }
    }
}
largest

これは印刷します:

kind: Square
kind: Prime
kind: Fibonacci

1
どうもありがとうございます!しばらく困惑した。私はそれを解体するために各キーの番号を追加したり削除したりし続けましたが、どこにも行きませんでした。あなたの説明は非常に明確です。
Nick Kohrn 2014年

15
let dict : [String : Any] = ["FirstName" : "Maninder" , "LastName" : "Singh" , "Address" : "Chandigarh"]
dict.forEach { print($0) }

結果は

( "FirstName"、 "Maninder")( "LastName"、 "Singh")( "Address"、 "Chandigarh")


この例が1,000データループでより効率的かどうか教えてください。なぜなら、私にはそれほど大きなJSONがあるため、最後に1GBの処理が必要になるからです。新しいデバイスはクラッシュしませんが、私のiphone 5sではその半分で16GBがクラッシュします。
Daniel Arantes Loverde 2017

元の質問が辞書が順序を維持するかどうかに関するものである場合、これは少し誤解を招くようです。次に、辞書が順序を維持しない例を投稿します。
Declan McKenna

12

これは、辞書を反復するユーザー定義関数です。

func findDic(dict: [String: String]){
    for (key, value) in dict{
    print("\(key) : \(value)")
  }
}

findDic(dict: ["Animal":"Lion", "Bird":"Sparrow"])
//prints Animal : Lion 
         Bird : Sparrow

11

これがその実験の代替案です(Swift 3.0)。これにより、どの種類の数が最大であったかが正確にわかります。

let interestingNumbers = [
"Prime": [2, 3, 5, 7, 11, 13],
"Fibonacci": [1, 1, 2, 3, 5, 8],
"Square": [1, 4, 9, 16, 25],
]

var largest = 0
var whichKind: String? = nil

for (kind, numbers) in interestingNumbers {
    for number in numbers {
    if number > largest {
        whichKind = kind
        largest = number
    }
  }
}

print(whichKind)
print(largest)

OUTPUT:
Optional("Square")
25

8

すべての値を反復処理する場合:

dict.values.forEach { value in
    // print(value)
}

私は事実がとても嫌いで、これは正しいです。愚かなジョーダは誰もが話さなければならない迅速なクリエイターに話します!🤮
セバスチャン


1

を使用values.makeIterator()して、次のようにdict値を反復することもできます。

for sb in sbItems.values.makeIterator(){
    // do something with your sb item..
    print(sb)
}

より迅速なスタイルで、次のような反復を行うこともできます。

sbItems.values.makeIterator().forEach{
    // $0 is your dict value..
    print($0) 
}

* sbItemsタイプの辞書です[String : NSManagedObject]

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.