배열에 동적으로 데이터를 추가할 때에는 메소드를 사용하는데,
기능에 따라 다양한 메소드가 있지만 대표적인 것으로 세 가지 정도 사용한다.
- append(_:)
- insert(_:at:)
- append(contentsOf:)
1. append(_:)
append(_:) 메소드는 입력된 값을 배열의 맨 뒤에 추가한다.
일반적으로 배열에서 존재하지 않는 인덱스에 접근하면 오류가 발생하므로 이 메소드는 데이터 추가 전에 먼저 배열의 크기를 +1만큼 확장하여 인덱스 공간을 확보한 후, 인자값을 마지막 인덱스 위치에 추가한다.
2. insert(_:at:)
insert(_:at:) 메소드는 데이터를 배열의 맨 뒤가 아닌 원하는 위치에 직접 추가하고 싶을 때 사용한다.
at: 뒤에 입력되는 정수값은 배열에서 데이터가 추가될 인덱스의 위치를 의미한다.
이 인덱스에 새로운 값이 추가되면 이를 기준으로 하여 나머지 인덱스들은 하나씩 다음으로 밀려나는 결과를 가져온다.
📝 쉽게 말해서 끼어들기 🤬
3. append(contentsOf:)
append(contentsOf:)는 append(_:) 메소드 처럼 배열의 맨 마지막에 데이터를 추가하지만, 개별 데이터가 아니라 여러 개의 데이터를 배열에 한꺼번에 추가할 때 사용하는 메소드이다. 이를 위해 메소드의 인자값은 항상 배열이어야 한다.
4. 추가
메소드를 이용하여 배열 데이터를 동적으로 추가해 보자.
// 문자열을 아이템으로 갖는 배열 선언 및 초기화
var city = [String]()
city.append("Seoul")
city.append("New York")
city.insert("Tokyo",at: 1)
city.append(contentsOf: ["Dubai", "Sydney"])
데이터가 추가된 배열 city는 코드를 실행해 보면 다음과 같은 데이터 및 인덱스 순서로 구성된다.
입력된 값을 변경하고 싶을 때는 배열의 인덱스를 이용하여 변경할 값을 직접 대입하면 된다.
city[2] = "Madrid"
🙂 :수정할 값을 직접 대입하는 방법으로 기존의 값을 변경할 수 있다면, 처음부터 이렇게 값을 입력할 수는 없을까?
var city = [String]()
city[0] = "Seoul"
city[1] = "Tokyo"
city[2] = "Madrid"
city[3] = "Dubai"
city[4] = "Sydney"
결론부터 이야기하자면 틀렸다.
배열의 인덱스를 이용하여 직접 아이템에 접근하는 이 방식으로 기존에 있는 값을 수정할 수 있지만, 값을 추가할 수는 없다.
어떤 경우든지 배열의 인덱스를 직접 이용하여 데이터의 값을 할당하거나 수정하고, 읽어오는 것은 해당 배열에 그 인덱스가 이미 만들어져 있거나 그만큼의 인덱스가 확보된 경우로 제한된다.
📝 간단하게 줄여서 이미 만들어져 있어야 가능하다는 뜻이다
그렇지 않을 경우 배열은 존재하지 않는 인덱스를 참조하려고 시도하고, 그 결과로 오류가 발생한다.
잘못된 인덱스 참조로 인한 오류가 생기는 것이다.
// 배열 선언 및 초기화
var city = [String]()
// 배열 추가
city,insert("Seoul",at:0)
배열의 인덱스에 직접 접근하려면 접근할 인덱스 공간이 미리 만들어져 있어야 한다.
지금까지 배열을 만들 때 배열에 들어갈 데이터의 개수, 즉 배열의 길이를 그다지 고려하지 않았다. 처음에 시작할 때 크기를 0으로 지정한 후 입력 메소드를 사용하여 새로운 데이터를 추가할 때마다 동적으로 크기가 늘어나도록 배열을 사용했다.
배열의 길이가 늘어나면 그만큼 인덱스도 자동으로 늘어나는 것이 스위프트에서 배열의 특징이다.
하지만 이렇게 하면 배열의 크기는 언제나 현재 입력된 값의 개수만큼 생성된다.
새로운 데이터를 직접 할당하기 위해 참조해야 할 인덱스는 아직 생성되어 있지 않은 상태다. 이 때문에 오류가 발생하기도 한다.
배열의 크기를 동적으로 변경하는 방식으로 생성한 배열은 새로운 데이터를 추가할 목적으로 인덱스에 직접 접근할 수 없다. 다만 코코아 터치 프레임워크를 살펴보면 배열을 생성하는 여러 가지 방법 중에서 초기화할 때 배열의 크기를 지정할 수 있는 구문이 아래와 같이 정의되어 있다.
extension Array : RangeReplaceableCollection {
public init(repeating repeatedValue: Element, count: Int)
}
'메모장' 카테고리의 다른 글
Swift 집합 (1) | 2023.03.21 |
---|---|
Swift 범위 연산자를 이용한 인덱스 참조 (1) | 2023.03.20 |
Swift 배열의 동적 선언과 초기화 (1) | 2023.03.15 |
Swift 배열 순회 탐색 (3) | 2023.03.14 |
Swift 배열 (4) | 2023.03.13 |