Bibi's DevLog πŸ€“πŸŽ

[Swift 자료ꡬ쑰] 2. Dictionary λ”•μ…”λ„ˆλ¦¬ (생성, CRUD) λ³Έλ¬Έ

ν”„λ‘œκ·Έλž˜λ°/Data Structures 자료ꡬ쑰

[Swift 자료ꡬ쑰] 2. Dictionary λ”•μ…”λ„ˆλ¦¬ (생성, CRUD)

λΉ„λΉ„ bibi 2022. 12. 16. 16:00

Apple Developer Documentation

Data Structure in Swift (iOS)β€Š-β€ŠPart 1

μœ„ 두 λ¬Έμ„œλ₯Ό μ°Έκ³ ν•΄ μž‘μ„±ν–ˆμŠ΅λ‹ˆλ‹€.

Dictionary λ”•μ…”λ„ˆλ¦¬

: ν‚€-κ°’ μŒμ„ μš”μ†Œλ‘œ κ°–λŠ” μ»¬λ ‰μ…˜.

@frozen struct Dictionary<Key, Value> where Key : Hashable

μ†Œκ°œ

λ”•μ…”λ„ˆλ¦¬λŠ” ν•΄μ‹œ ν…Œμ΄λΈ”μ˜ 일쒅이닀. (λ‹€λ₯Έ μ–Έμ–΄μ—μ„œλŠ” hashes λ‚˜ associated arrays라고도 λΆˆλ¦°λ‹€)

  • ν•­λͺ©λ“€μ— λŒ€ν•œ λΉ λ₯Έ 접근이 κ°€λŠ₯ν•˜λ‹€

λ”•μ…”λ„ˆλ¦¬μ˜ 각 ν•­λͺ©μ€ ν‚€keyλ₯Ό 톡해 κ΅¬λ³„λ˜λ©°, 킀에 μƒμ‘ν•˜λŠ” κ°’value을 가진닀.

  • ν‚€λŠ” hashableν•œ νƒ€μž…μ΄μ–΄μ•Ό ν•œλ‹€.
    • Hashable ν”„λ‘œν† μ½œμ„ μ€€μˆ˜ν•˜λŠ” λͺ¨λ“  νƒ€μž…μ€ ν‚€κ°€ 될 수 μžˆλ‹€.
  • ν‚€λŠ” μƒμ‘ν•˜λŠ” 값을 μ°ΎκΈ° μœ„ν•΄ μ‚¬μš©λœλ‹€.
  • 값은 μ–΄λ–€ 객체든 ν• λ‹Ήν•  수 μžˆλ‹€.

λ”•μ…”λ„ˆλ¦¬μ˜ νŠΉμ§•

  • μˆœμ„œλ₯Ό 보μž₯ν•˜μ§€ μ•ŠλŠ”λ‹€.
    • μš”μ†Œλ₯Ό 넣은 μˆœμ„œλŒ€λ‘œ μ •λ¦¬λ˜μ–΄ μžˆμ§€ μ•Šλ‹€.
    • μ»¬λ ‰μ…˜μ΄ λ³€κ²½λ˜κΈ° μ „κΉŒμ§€λŠ” μš”μ†Œμ˜ μˆœμ„œκ°€ μœ μ§€λœλ‹€.

λ”•μ…”λ„ˆλ¦¬ μƒμ„±ν•˜κΈ°

λ”•μ…”λ„ˆλ¦¬ λ¦¬ν„°λŸ΄([:])을 톡해 생성이 κ°€λŠ₯ν•˜λ‹€.

  • μ‰Όν‘œλ‘œ κ΅¬λΆ„λœ ν‚€:κ°’ 쌍으둜 이루어져 μžˆλ‹€.
  • 각각의 ν‚€λŠ” μ—°κ΄€λœ 값을 가진닀.

μƒμˆ˜/λ³€μˆ˜μ— λ”•μ…”λ„ˆλ¦¬λ₯Ό ν• λ‹Ήν•˜κ±°λ‚˜, ν•¨μˆ˜μ— λ”•μ…”λ„ˆλ¦¬λ₯Ό λ„˜κΈ°λŠ” 것도 κ°€λŠ₯ν•˜λ‹€.

// λ”•μ…”λ„ˆλ¦¬ λ§Œλ“€κΈ° - HTTP 응닡 μ½”λ“œμ™€ μ—°κ΄€ λ©”μ‹œμ§€
var responseMessages = [200: "OK",
                        403: "Access forbidden",
                        404: "File not found",
                        500: "Internal server error"]

// 빈 λ”•μ…”λ„ˆλ¦¬ λ§Œλ“€κΈ°  - 킀와 κ°’μ˜ νƒ€μž…μ„ μ„ μ–Έ μ‹œ λͺ…μ‹œν•΄μ•Ό 함
var emptyDict: [String: String] = [:]

λ”•μ…”λ„ˆλ¦¬μ— 값을 λ„£κ±°λ‚˜ κ°€μ Έμ˜€κΈ° (CRUD)

λ”•μ…”λ„ˆλ¦¬μ˜ κ°’ κ°€μ Έμ˜€κΈ° - μ„œλΈŒμŠ€ν¬λ¦½νŠΈ

  • λ”•μ…”λ„ˆλ¦¬μ˜ ν‚€ 값을 μ„œλΈŒμŠ€ν¬λ¦½νŠΈλ‘œ ν™œμš©ν•΄ 값을 κ°€μ Έμ˜¬ 수 μžˆλ‹€. O(1).
    • μ˜΅μ…”λ„ 값을 λ¦¬ν„΄ν•œλ‹€ - κ·Έ 킀에 ν•΄λ‹Ήν•˜λŠ” 값이 μ—†λŠ” 경우 nil을 λ°˜ν™˜ν•˜κΈ° μœ„ν•΄.
print(responseMessages[200])
// Prints "Optional("OK")"

let httpResponseCodes = [200, 403, 301]
for code in httpResponseCodes {
    if let message = responseMessages[code] {
        print("Response \(code): \(message)")
    } else {
        print("Unknown response \(code)")
    }
}
// Prints "Response 200: OK"
// Prints "Response 403: Access forbidden"
// Prints "Unknown response 301"
  • contains(where:) : O(n)
    • 쑰건에 ν•΄λ‹Ήν•˜λŠ” 값이 μžˆλŠ”μ§€ μ—†λŠ”μ§€ 확인할 수 μžˆλ‹€.

λ”•μ…”λ„ˆλ¦¬μ˜ κ°’ κ°€μ Έμ˜€κΈ° - 인덱슀

  • index(forKey:) : 평균 O(1)
    • 주어진 킀에 λŒ€ν•œ 인덱슀λ₯Ό λ°˜ν™˜ν•œλ‹€.
  • firstIndex(where:) : 쑰건에 ν•΄λ‹Ήν•˜λŠ” 인덱슀λ₯Ό 찾을 수 μžˆλ‹€.
    • μ„œλΈŒμŠ€ν¬λ¦½νŠΈμ™€ 달리, 인덱슀λ₯Ό 톡해 λ”•μ…”λ„ˆλ¦¬ 값을 κ°€μ Έμ˜€λ©΄ ν‚€-κ°’ μŒμ„ μ˜΅μ…”λ„ 없이 λ°˜ν™˜ν•œλ‹€.
let imagePaths = ["star": "/glyphs/star.png",
                  "portrait": "/images/content/portrait.jpg",
                  "spacer": "/images/shared/spacer.gif"]

let glyphIndex = imagePaths.firstIndex(where: { $0.value.hasPrefix("/glyphs") })
if let index = glyphIndex {
    print("The '\(imagePaths[index].key)' image is a glyph.")
} else {
    print("No glyphs found!")
}
// Prints "The 'star' image is a glyph.")

print(imagePaths[glyphIndex!])
// Prints "(key: "star", value: "/glyphs/star.png")"
  • ❗️ λ”•μ…”λ„ˆλ¦¬μ˜ μΈλ±μŠ€λŠ” 버퍼λ₯Ό μΆ”κ°€ ν• λ‹Ήν•˜μ§€ μ•Šκ³  값을 계속 μ €μž₯ν•  수 μžˆλŠ” λ™μ•ˆμ€ μœ νš¨μ„±μ΄ μœ μ§€λœλ‹€. ν•˜μ§€λ§Œ λ”•μ…”λ„ˆλ¦¬κ°€ μ»€μ Έμ„œ 버퍼λ₯Ό λŠ˜λ €μ•Ό ν•œλ‹€λ©΄, 기쑴의 μΈλ±μŠ€λ“€μ΄ μ•„λ¬΄λŸ° κ²½κ³  없이 μœ νš¨μ„±μ΄ μ—†μ–΄μ§ˆ 수 μžˆλ‹€.
    • λ”°λΌμ„œ λ§Œμ•½ λ”•μ…”λ„ˆλ¦¬μ— ν• λ‹Ήν•  κ°’μ˜ 수λ₯Ό μ•Œκ³  μžˆλ‹€λ©΄, init(minimumCapacity:) μƒμ„±μžλ₯Ό μ‚¬μš©ν•΄ μ μ ˆν•œ 크기의 버퍼λ₯Ό 미리 ν• λ‹Ήν•΄μ•Ό ν•œλ‹€.

λ”•μ…”λ„ˆλ¦¬μ— κ°’ μ‚½μž…ν•˜κΈ°, μˆ˜μ •ν•˜κΈ°, μ‚­μ œν•˜κΈ°

값을 κ°€μ Έμ˜¬ λ•Œμ™€ λ§ˆμ°¬κ°€μ§€λ‘œ μ„œλΈŒμŠ€ν¬λ¦½νŠΈλ₯Ό ν™œμš©ν•œλ‹€.

  • κ°’ μ‚½μž…ν•˜κΈ° : μƒˆλ‘œμš΄ 킀에 μΆ”κ°€ν•  값을 ν• λ‹Ήν•œλ‹€.
  • κ°’ μˆ˜μ •ν•˜κΈ° : κΈ°μ‘΄ 킀에 μˆ˜μ •ν•  μƒˆλ‘œμš΄ 값을 ν• λ‹Ήν•œλ‹€.
  • κ°’ μ‚­μ œν•˜κΈ° : κΈ°μ‘΄ 킀에 nil을 ν• λ‹Ήν•œλ‹€.

μ‚­μ œ, μˆ˜μ •μ€ λ°°μ—΄μ²˜λŸΌ μ œκ³΅λ˜λŠ” λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•  μˆ˜λ„ μžˆλ‹€.

  • e.g. κ°’ μ‚­μ œ : remove(at:), removeValue(forKey:), removeAll(keepingCapacity:) . λͺ¨λ‘ O(n).
responseMessages[301] = "Moved permanently" // κ°’ μ‚½μž…ν•˜κΈ°
print(responseMessages[301])
// Prints "Optional("Moved permanently")"

responseMessages[404] = "Not found" // κ°’ μˆ˜μ •ν•˜κΈ°
responseMessages[500] = nil // κ°’ μ‚­μ œν•˜κΈ°
print(responseMessages)
// Prints "[301: "Moved permanently", 200: "OK", 403: "Access forbidden", 404: "Not found"]"

λ³€μˆ˜μΈ λ”•μ…”λ„ˆλ¦¬ μΈμŠ€ν„΄μŠ€μ— λŒ€ν•΄μ„œλŠ”, ν‚€λ₯Ό 톡해 μ ‘κ·Όν•œ 값을 μ œμžλ¦¬μ—μ„œ μˆ˜μ •ν•  μˆ˜λ„ μžˆλ‹€.

  • μ•„λž˜ μ˜ˆμ‹œλŠ” [String:[Int]] νƒ€μž…μ˜ λ”•μ…”λ„ˆλ¦¬λ₯Ό μ„ μ–Έν•˜κ³ , μ œμžλ¦¬μ—μ„œ 각각의 κ°’([Int]) 을 λ‚΄λ¦Όμ°¨μˆœμœΌλ‘œ μ •λ ¬ν•˜κ³  μžˆλ‹€.
var interestingNumbers = ["primes": [2, 3, 5, 7, 11, 13, 17],
                          "triangular": [1, 3, 6, 10, 15, 21, 28],
                          "hexagonal": [1, 6, 15, 28, 45, 66, 91]]
for key in interestingNumbers.keys {
    interestingNumbers[key]?.sort(by: >)
}

print(interestingNumbers["primes"]!)
// Prints "[17, 13, 11, 7, 5, 3, 2]"

λ”•μ…”λ„ˆλ¦¬μ˜ λ‚΄μš© λ°˜λ³΅ν•˜κΈ°(μˆœνšŒν•˜κΈ°)

λ”•μ…”λ„ˆλ¦¬λŠ” μˆœμ„œκ°€ μ—†λŠ” ν‚€-κ°’ 쌍의 μ»¬λ ‰μ…˜μ΄λ‹€.

  • ν‚€-κ°’ 쌍의 μˆœμ„œλŠ” λ”•μ…”λ„ˆλ¦¬μ— λ³€ν™”(μ‚½μž…, μ‚­μ œ, μˆ˜μ • λ“±)κ°€ μΌμ–΄λ‚˜κΈ° μ „κΉŒμ§€λŠ” μœ μ§€λ˜λ‚˜, λ³€ν™”κ°€ μΌμ–΄λ‚œ ν›„μ—λŠ” μˆœμ„œλ₯Ό μ˜ˆμΈ‘ν•  수 μ—†λ‹€.
  • λ§Œμ•½ ν‚€-κ°’ μŒμ„ μ‚¬μš©ν•˜λ©΄μ„œλ„ μˆœμ„œκ°€ μžˆλŠ” μ»¬λ ‰μ…˜μ„ μ“°κ³  μ‹Άκ³ , λ”•μ…”λ„ˆλ¦¬μ™€ 같은 λΉ λ₯Έ ν‚€ 탐색이 ν•„μš”μ—†λ‹€λ©΄, KeyValuePairs λΌλŠ” νƒ€μž…μ„ λ”•μ…”λ„ˆλ¦¬ λŒ€μ‹  μ‚¬μš©ν•  수 μžˆλ‹€.

λ”•μ…”λ„ˆλ¦¬λ₯Ό μˆœνšŒν•˜κΈ° μœ„ν•΄μ„œλŠ” for-in 루프λ₯Ό μ‚¬μš©ν•΄μ•Ό ν•œλ‹€.

  • ν‚€-κ°’ μŒμ„ νŠœν”Œμ˜ μš”μ†Œλ‘œ λΆ„ν•΄ν•΄ μ‚¬μš©ν•  수 μžˆλ‹€.
let imagePaths = ["star": "/glyphs/star.png",
                  "portrait": "/images/content/portrait.jpg",
                  "spacer": "/images/shared/spacer.gif"]

for (name, path) in imagePaths {
    print("The path to '\(name)' is '\(path)'.")
}
// Prints "The path to 'star' is '/glyphs/star.png'."
// Prints "The path to 'portrait' is '/images/content/portrait.jpg'."
// Prints "The path to 'spacer' is '/images/shared/spacer.gif'."