วนซ้ำในพจนานุกรมอย่างรวดเร็ว


222

ฉันสับสนเล็กน้อยกับคำตอบที่ 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จำนวนมากที่สุดจะถูกกำหนดให้ตัวแปร อย่างไรก็ตามฉันสับสนว่าทำไม Xcode จึงบอกว่าlargestตั้งค่า 5 ครั้งหรือ 1 ครั้งหรือ 3 ครั้งขึ้นอยู่กับการทดสอบแต่ละครั้ง

เมื่อดูรหัสฉันเห็นว่าควรตั้งค่า 6 ครั้งใน "Prime" เพียงอย่างเดียว (2, 3, 5, 7, 11, 13) จากนั้นควรข้ามตัวเลขใด ๆ ใน "Fibonacci" เนื่องจากตัวเลขเหล่านั้นน้อยกว่าจำนวนที่ใหญ่ที่สุดซึ่งปัจจุบันตั้งค่าเป็น 13 จาก "Prime" จากนั้นควรตั้งค่าเป็น 16 และสุดท้าย 25 ใน "Square" ให้ผลรวม 8 ครั้ง

ฉันขาดอะไรบางอย่างที่ชัดเจนอย่างสิ้นเชิง?

คำตอบ:


355

ไม่มีการเรียงลำดับพจนานุกรมใน Swift (และภาษาอื่น ๆ ) เมื่อคุณวนซ้ำในพจนานุกรมไม่มีการรับประกันว่าคำสั่งซื้อจะตรงกับลำดับการเริ่มต้น ในตัวอย่างนี้ Swift ประมวลผลคีย์ "Square" ต่อหน้าส่วนอื่น คุณสามารถเห็นสิ่งนี้ได้โดยการเพิ่มคำสั่งพิมพ์ลงในลูป 25 คือองค์ประกอบที่ 5 ของ Square ดังนั้นที่ใหญ่ที่สุดจะถูกตั้งค่า 5 ครั้งสำหรับ 5 องค์ประกอบใน Square แล้วจะอยู่ที่ 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

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

ผลก็จะเป็น

("FirstName", "Maninder") ("LastName", "Singh") ("ที่อยู่", "Chandigarh")


คุณช่วยบอกฉันได้ไหมว่าตัวอย่างนี้มีประสิทธิภาพมากกว่าใน data loop 1,000 รายการ เพราะฉันมี JSON ที่ใหญ่ดังนั้นจึงใช้การประมวลผล 1GB ในตอนท้าย อุปกรณ์รุ่นใหม่จะไม่ผิดพลาด แต่ใน iphone 5s 16GB ของฉันผิดพลาดครึ่งหนึ่งของสิ่งนั้น
Daniel Arantes Loverde

ดูเหมือนว่าจะทำให้เข้าใจผิดเล็กน้อยจากคำถามเดิมเกี่ยวกับว่าพจนานุกรมรักษาคำสั่งซื้อของคุณหรือไม่แล้วคุณโพสต์ตัวอย่างที่พวกเขารักษาคำสั่งซื้อของพวกเขาเมื่อพวกเขาไม่
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)
}

ฉันเกลียดความจริงที่มากขนาดนี้ ใน Joda ที่โง่พูดกับผู้สร้างที่รวดเร็วทุกคนต้องพูด! 🤮
เซบาสเตียน

4

อาร์เรย์เป็นชุดคำสั่ง แต่พจนานุกรมและชุดเป็นชุดที่ไม่เรียงลำดับ ดังนั้นคุณไม่สามารถทำนายลำดับของการวนซ้ำในพจนานุกรมหรือชุด

อ่านบทความนี้เพื่อทราบข้อมูลเพิ่มเติมเกี่ยวกับ ประเภทการเก็บ: ภาษาการเขียนโปรแกรม Swift


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คือ dict ชนิด[String : NSManagedObject]

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.