[Swift] Arrays (๋ฐฐ์—ด)

LEEHAKJIN-VVยท2022๋…„ 5์›” 3์ผ
0

Study-Swift 5.6

๋ชฉ๋ก ๋ณด๊ธฐ
1/22

์ฐธ๊ณ ์‚ฌ์ดํŠธ:
The swift Language Guide
Apple Developer
boostcourse


๐Ÿ’ช ๋ฐฐ์—ด(Arrays)

  • ์ˆœ์„œ๊ฐ€ ์žˆ๋Š” ๋ฆฌ์ŠคํŠธ ์ปฌ๋ ‰์…˜
  • ์ฆ‰ ๋ฆฌ์ŠคํŠธ ์•ˆ์— ์‚ฝ์ž…๋œ ๋ฉค๋ฒ„๊ฐ€ ์ˆœ์„œ(์ธ๋ฑ์Šค)๋ฅผ ๊ฐ€์ง„ ์ปฌ๋ ‰์…˜

๐Ÿฅธ ๋ฐฐ์—ด ์„ ์–ธ๋ฐฉ๋ฒ•

  • ๋ฐฐ์—ด ํƒ€์ž…์€ Array๋กœ ํ‘œํ˜„ํ•˜๊ณ  ์„ ์–ธ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ•œ๋‹ค.
var examInt: Array<Int> = Array<Int>()
// ์„ ์–ธ์˜ ์ถ•์•ฝํ˜•
var examInt: [Int] = []

๐Ÿฅธ ๋นˆ ๋ฐฐ์—ด ์ƒ์„ฑ๋ฐฉ๋ฒ•

var examInt: [Int] = [Int]()
examInt.append(3)
// insert value 3
examInt = []
// array clear

๐Ÿฅธ ๊ธฐ๋ณธ ๊ฐ’์œผ๋กœ ๋นˆ ๋ฐฐ์—ด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•

  • init(repeating repeatedValue: Element, count: Int)
    • repating:๋ฐ˜๋ณตํ•˜๋Š” ๊ฐ’
    • count: ๋ฐ˜๋ณตํ•˜๋Š” ํšŸ์ˆ˜(์ฆ‰ ๊ธธ์ด๋ฅผ ๋ฏธ๋ฆฌ ์ง€์ •)
var threeDoubles = Array(repeating: 0.0, count: 3)
// threeDoubles : Double ํƒ€์ž…์˜ [0.0, 0.0, 0.0]

์ด๊ฒƒ์€ ๋ฐฐ์—ด๋ง๊ณ ๋„ String์—์„œ๋„ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

let cake: String = String(repeating: "์น˜์ฆˆ์ผ€์ดํฌ",count: 3)
>>> "์น˜์ฆˆ์ผ€์ดํฌ์น˜์ฆˆ์ผ€์ดํฌ์น˜์ฆˆ์ผ€์ดํฌ"

๐Ÿฅธ ๋‹ค๋ฅธ ๋ฐฐ์—ด๋ฅผ ์ถ”๊ฐ€ํ•œ ๋ฐฐ์—ด์˜ ์ƒ์„ฑ

  • "+" ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ฐฐ์—ด๋ฅผ ํ•ฉ์น  ์ˆ˜ ์žˆ๋‹ค.
var anotherThreeDoubles = Array(repeating: 2.5, count: 3)
// anotherThreeDoubles : [2.5, 2.5, 2.5]

var sixDoubles = threeDoubles + anotherThreeDoubles
// sixDoubles : [0.0, 0.0, 0.0, 2.5, 2.5, 2.5]

๐Ÿฅธ ๋ฆฌํ„ฐ๋„์„ ์ด์šฉํ•œ ๋ฐฐ์—ด์˜ ์ƒ์„ฑ

[value1, value2, value3] ํ˜•ํƒœ๋ฅผ ์ด์šฉํ•ด ๋ฐฐ์—ด์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

var shoppingList: [String] = ["Eggs", "Milk"]
var shoppingList = ["Eggs", "Milk"]
shoppingList.append("Meat)
// ๋ฆฌํ„ฐ๋„์„ ์ด์šฉํ•œ ๋ฐฐ์—ด ์ƒ์„ฑ๋„ ๊ฐ’ ์ถ”๊ฐ€ ๋ณ€๊ฒฝ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

๐Ÿฅธ ๋ฐฐ์—ด์˜ ์›์†Œ ๊ฐœ์ˆ˜ ํ™•์ธ์€ count ํ”„๋กœํผํ‹ฐ๋ฅผ ์ด์šฉํ•˜์—ฌ ํ™•์ธ๊ฐ€๋Šฅ

print("The shopping list contains \(shoppingList.count) items.")
// The shopping list contains 3 items.

๐Ÿฅธ ๋ฐฐ์—ด์ด ๋น„์—ˆ๋Š”์ง€ ํ™•์ธ์€ isEmpty ํ”„๋กœํผํ‹ฐ๋ฅผ ์ด์šฉํ•˜์—ฌ ํ™•์ธ ๊ฐ€๋Šฅ

if shoppingList.isEmpty{
    print("I don't know shopping list")
} else{
    print("I know \(shoppingList.count) shopping list")
}
// prints "I know 3 shopping list"

๐Ÿฅธ ๋ฐฐ์—ด์— ์›์†Œ์ถ”๊ฐ€ ๋ฐฉ๋ฒ•

  • 3๊ฐ€์ง€ ๋ฐฉ๋ฒ•์œผ๋กœ ๋ฐฐ์—ด์— ์›์†Œ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ๋‹จ์ˆœ append ๋ฉ”์†Œ๋“œ์˜ ์‚ฌ์šฉ์€ ๋‹จ์ผ element๋ฅผ ์‚ฝ์ž…ํ• ๋•Œ ์‚ฌ์šฉ.
var students = ["Ben", "Ivy", "Jordell"]
students.append("Maxime")
// ["Ben", "Ivy", "Jordell", "Maxime"]
  • append๋ฉ”์†Œ๋“œ์˜ contensOf ์˜ต์…˜์„ ์‚ฌ์šฉํ•˜๋ฉด ๋‹ค์ค‘ element๋ฅผ ์‚ฝ์ž…๊ฐ€๋Šฅ.
students.append(contentsOf: ["Shakia", "William"])
// ["Ben", "Ivy", "Jordell", "Maxime", "Shakia", "William"]
  • "+"์—ฐ์‚ฐ์„ ์ด์šฉํ•ด์„œ ๋‹ค์ค‘ element ์‚ฝ์ž… ๊ฐ€๋Šฅ.
students += ["Jack","Steven"]
// ["Ben", "Ivy", "Jordell", "Maxime", "Shakia", "William", "Jack","Steven"]
  • Insert ๋ฉ”์†Œ๋“œ๋ฅผ ์ด์šฉํ•˜์—ฌ ํŠน์ •์œ„์น˜์˜ ์ธ๋ฑ์Šค์— ๊ฐ’ ์‚ฝ์ž… ๊ฐ€๋Šฅ.
students.insert("Liam", at: 3)
// ["Ben", "Ivy", "Jordell", "Liam", "Maxime", "Shakia", "William", "Jack", "Steven"]

๐Ÿฅธ ๋ฐฐ์—ด ์›์†Œ ์ œ๊ฑฐ ๋ฐฉ๋ฒ•

  • ๋ฐฐ์—ด์˜ ์›์†Œ ์ œ๊ฑฐ๋Š” remove ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
students.remove(at: 0)
//students.removeFirst() // ๋™์ผํ•œ ํ‘œํ˜„
// ["Ivy", "Jordell", "Liam", "Maxime", "Shakia", "William", "Jack", "Steven"]

students.removeLast()
// ["Ivy", "Jordell", "Liam", "Maxime", "Shakia", "William", "Jack"]

// ์‚ญ์ œํ•  ์ธ๋ฑ์Šค ๋ฒ”์œ„๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค -> (1,2) ์ธ๋ฑ์Šค ์œ„์น˜์— ์žˆ๋Š” ๊ฐ’ ์ œ๊ฑฐ
students.removeSubrange(1..<3)
// ["Ivy", "Maxime", "Shakia", "William", "Jack"]

๐Ÿฅธ ๋ฐฐ์—ด ํŠน์ • element ๊ฐ’ ๋ณ€๊ฒฝ

  • ์ˆ˜์ •ํ•˜๊ณ ์ž ํ•˜๋Š” element์˜ ์ธ๋ฑ์Šค๋ฅผ ๋ชจ๋ฅด๊ณ  ๊ฐ’๋งŒ ์•Œ ๊ฒฝ์šฐ.
if let i = students.firstIndex(of: "William"){
    students[i] = "Will"
}
// ["Maxime", "Will", "Jack"]
  • ์ธ๋ฑ์Šค์˜ ์œ„์น˜๋ฅผ ์•Œ๊ณ  ์žˆ์œผ๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด element๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.
students[1] = "Jujo"
// "Maxime", "Jujo", "Jack"]
  • 1๊ฐœ์˜ ๊ฐ’์ด ์•„๋‹Œ ์—ฌ๋Ÿฌ๊ฐœ์˜ ๊ฐ’์„ ํ•œ๋ฒˆ์— ์ˆ˜์ •์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
students[1...2] = ["Haha", "Hongchul"]
//["Maxime", "Haha", "Hongchul"]

๐Ÿฅธ ๋ฐฐ์—ด values ์ ‘๊ทผ

  • ๋ฐฐ์—ด์˜ ์›์†Œ ์ ‘๊ทผ์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.
    • if let ํ‘œํ˜„์‹์€ ์ถ”ํ›„ ํ•™์Šตํ•  ์˜ˆ์ •
// ์•ˆ์ „ํ•œ ๋ฐฉ๋ฒ• 
let oddNumbers = [1, 3, 5, 7, 9, 11, 13, 15]
if let firstElement = oddNumbers.first, let lastElement = oddNumbers.last {
    print(firstElement, lastElement, separator: ", ")
}
// print 1, 15

let emptyDouble: [Double] = []
print(emptyDouble.first, emptyDouble.last, separator: ", ")

//๋งŒ์•ฝ array๊ฐ€ empty๋ผ๋ฉด nill ์ถœ๋ ฅ
// print nil, nil


// a
print(emptyDouble[0])
// Triggers runtime error: Index out of range

๐Ÿฅธ ๋ฐฐ์—ด ์ˆœํšŒ

  • "for-in loop" ์‚ฌ์šฉ.
let cities:[String] = ["์ง„ํ•ด","๋งˆ์‚ฐ","์ฐฝ์›"]

for city in cities {
    print("I don't live in \(city)")
}
// I don't live in ์ง„ํ•ด
// I don't live in ๋งˆ์‚ฐ
// I don't live in ์ฐฝ์›
  • index์™€ value ๋‘˜๋‹ค ์ ‘๊ทผ์ด ํ•„์š”ํ• ์‹œ "enumerate" ๋ฉ”์†Œ๋“œ ์‚ฌ์šฉ.
for(n,c) in cities.enumerated(){
    print("\(n): '\(c)'")
}
// 0: '์ง„ํ•ด'
// 1: '๋งˆ์‚ฐ'
// 2: '์ฐฝ์›'

๐Ÿ‘€ ๋ฐฐ์—ด์˜ ๋ณต์‚ฌ๋ณธ ์ˆ˜์ •

  • Arrray๋Š” ๊ตฌ์กฐ์ฒด๋กœ ๊ตฌํ˜„๋˜์–ด ์žˆ๊ณ , ๊ตฌ์กฐ์ฒด๋Š” Swift์—์„œ Value Types์ด๋ผ๊ณ  ํ•œ๋‹ค. ์ด Value Types์€ ๋…๋ฆฝ์ ์ธ ์ธ์Šคํ„ด์Šค์ด๋ฉฐ, ์ž์‹ ๋งŒ์˜ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น์„ ๊ฐ€์ง„๋‹ค. ์˜ˆ๋ฅผ ๋“ค๋ฉด:
var numbers: [Int] = [1,2,3,4,5]
var numbersCopy = numbers
numbers[0] = 100

print(numbers)
// [100, 2, 3, 4, 5]
print(numbersCopy)
// [1, 2, 3, 4, 5]

๋‹ค์Œ๊ณผ ๊ฐ™์ด numbersCopy์— numbers๋ฅผ ๋ณต์‚ฌํ•˜๊ณ , numbers์˜ ๊ฐ’์„ ์ˆ˜์ •ํ•˜์—ฌ๋„ ๋…๋ฆฝ์ ์ธ ์ธ์Šคํ„ด์Šค ์ด๋ฏ€๋กœ ์„œ๋กœ์˜ ๊ฐ’์ด ๋‹ค๋ฅธ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
์ฆ‰ Swift์˜ Value Types ์ธ์Šคํ„ด์Šค๋Š” ๋ณต์‚ฌ๋ฅผ ํ• ๋•Œ ์ฐธ์กฐํ•˜๋Š” ๊ฐœ์ฒด์˜ ์ฃผ์†Œ๋ฅผ ๊ณต์œ ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์„ ๋…๋ฆฝ์ ์œผ๋กœ ๊ฐ€์ง„๋‹ค.

  • ๋‹ค์Œ์€ ๋ฐฐ์—ด์˜ elements๊ฐ€ class์˜ ์ธ์Šคํ„ด์Šค์ธ ๊ฒฝ์šฐ๋ฅผ ์‚ดํŽด๋ณด์ž
var firstInteger = [IntegerReference(),IntegerReference()]
var secondInteger = firstInteger

firstInteger[0].value = 100
print(secondInteger[0].value)
// Prints "100"

firstInteger[0] = IntegerReference()
print(firstIntegers[0].value)
// Prints "10"
print(secondInteger[0].value)
// Prints "100"

์ด ๊ฒฝ์šฐ๋Š” ๋ฐฐ์—ด์˜ element๊ฐ€ class์˜ ์ธ์Šคํ„ด์Šค์ด๋‹ค class๋Š” Swift์—์„œ Reference Types์ด๊ณ , Reference Types์˜ ์ธ์Šคํ„ด์Šค๋Š” ๋ชจ๋“  ์ƒˆ ์ธ์Šคํ„ด์Šค๊ฐ€ ๋™์ผํ•œ ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ๋ฅผ ๊ฐ€์ง„๋‹ค

๊ทธ๋Ÿฌ๋ฏ€๋กœ ํ•œ๊ฐœ์˜ ๋ฐฐ์—ด์˜ ์ฐธ์กฐํ•˜๋Š” ์ธ์Šคํ„ด์Šค์˜ ๊ฐ’์ด ๋ณ€ํ•˜๋ฉด ์ด ์ธ์Šคํ„ด์Šค๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๋‹ค๋ฅธ ๋ฐฐ์—ด์˜ ๊ฐ’๋„ ๋ณ€ํ™”๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ๋งŒ์•ฝ, ๋ฐฐ์—ด์ด ์ƒˆ๋กœ ์ƒ์„ฑ๋œ ์ธ์Šคํ„ด์Šค๋ฅผ ์ฐธ์กฐํ•œ๋‹ค๋ฉด ์ด ๋‘˜์€ ์„œ๋กœ ์ฐธ์กฐํ•˜๋Š” ์ฃผ์†Œ๊ฐ€ ๋‹ค๋ฅด๋ฏ€๋กœ ์„œ๋กœ ๋…๋ฆฝ์  ๊ด€๊ณ„๊ฐ€ ๋˜๋Š”๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ทธ๋Ÿฌ๋ฉด Swift์˜ ๋ฐฐ์—ด์€ ๋ณต์‚ฌ ์‹œ ๋งค๋ฒˆ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ƒˆ๋กœ ํ• ๋‹นํ•  ๊นŒ??
๊ฒฐ๋ก ์€ ์•„๋‹ˆ๋‹ค!!
Swift์—์„œ๋Š” Value Types์— ๋Œ€ํ•ด copy-on-wirte optimization ์„ ์ œ๊ณตํ•œ๋‹ค.

A ๋ฐฐ์—ด, B ๋ฐฐ์—ด์ด ์žˆ๊ณ  ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ณต์‚ฌํ•œ ๊ฒฝ์šฐ

B = A

์ด ์‹œ์ ์—์„œ๋Š” B์™€ A๋Š” ๋™์ผํ•œ ์ €์žฅ์†Œ๋ฅผ ๊ณต์œ ํ•œ๋‹ค. ์ฆ‰ ์—ฌ๋Ÿฌ ๋ณต์‚ฌ๋ณธ์ด ์ˆ˜์ •์„ ๊ฑฐ์น˜๊ธฐ ์ „ ๊นŒ์ง€๋Š” ๋™์ผํ•œ ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ๋ฅผ ๊ณต์œ ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์ด A ๋ฐฐ์—ด์—์„œ ์ˆ˜์ •์ด ๋ฐœ์ƒํ•œ๋‹ค๋ฉด

A[0] = 11

A๋Š” ํ•ด๋‹น ๋ฐ์ดํ„ฐ์˜ ๋ณต์‚ฌ๋ณธ์„ ์ƒˆ๋กœ ๋งŒ๋“ค๊ณ  ์ด๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ๊ฒฐ๊ตญ ๊ธฐ์กด์—๋Š” ๋™์ผํ•œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ณต์œ ํ•˜๊ณ  ํ•„์š”ํ• ๋•Œ๋งŒ ๋ณต์‚ฌํ•˜์—ฌ ๋ณต์‚ฌ๋Ÿ‰์„ ์ค„์ด๊ณ  ์ตœ์ ํ™”๋ฅผ ์‹œํ‚ค๋Š” ๊ฒƒ์ด๋‹ค. ์ด๊ฒƒ์„ copy-on-write ๋ฐฉ์‹์ด๋ผ๊ณ  ํ•œ๋‹ค.

๋‹ค์Œ ์˜ˆ์‹œ์—์„œ๋Š” ๋™์ผํ•œ storage๋ฅผ ๊ณต์œ ํ•˜๋Š” ๋‘ ๊ฐœ์˜ ๋ณต์‚ฌ๋ณธ๊ฐ€ ์ˆซ์ž ๋ฐฐ์—ด์ด ์ƒ์„ฑ๋œ๋‹ค. ์›๋ž˜์˜ ๋ฐฐ์—ด์ด ์ˆ˜์ •๋˜๊ธฐ ์ „์— ๋ฐ์ดํ„ฐ์— ํ•ด๋‹นํ•˜๋Š” ์ €์žฅ์†Œ์˜ ๋…๋ฆฝ์ ์ธ ๋ณต์‚ฌ๋ณธ์„ ๋งŒ๋“ค๊ณ , ์ด ๋ณต์‚ฌ๋ณธ์— ๋Œ€ํ•ด ์ˆ˜์ •์ด ์ด๋ฃจ์–ด์ง„๋‹ค.

var numbers = [1,2,3,4,5]
var firstCopy = numbers
var secondCopy = numbers

// storage copy
numbers[0] = 100
numbers[1] = 200
numbers[2] = 300
// 'numbers' is [100, 200, 300, 4, 5]
// 'firstCopy' and 'secondCopy' are [1, 2, 3, 4, 5]

0๊ฐœ์˜ ๋Œ“๊ธ€