IdentifiedArray는 배열(Array)의 순서 보장 기능과 딕셔너리(Dictionary)의 빠른 접근성을 결합한 특수 컬렉션이다.
O(1)의 속도를 보장한다.IdentifiedArray는 Point-Free에서 만든 라이브러리로, Identifiable 프로토콜을 준수하는 객체들을 담는 컬렉션이다.
기존의 Array에서 특정 요소를 ID로 찾으려면 first(where:)를 사용해 전체 요소를 훑어야(O(n)) 했지만, IdentifiedArray를 사용하면 마치 딕셔너리처럼 ID를 통해 즉시(O(1)) 해당 요소에 접근할 수 있다. 그러면서도 딕셔너리와 달리 요소들의 순서를 엄격하게 유지한다.
IdentifiedArray는 내부적으로 Swift 공식 라이브러리인 swift-collections의 OrderedDictionary를 기반으로 설계되었다.
즉, "순서가 있는 딕셔너리"인데, Key가 데이터 내부의 id 프로토콜과 연결되어 있는 형태라고 이해하면 쉽다.
가장 흔하게 사용하는 일반 배열과 어떤 차이가 있는지 비교해보자.
| 비교 항목 | Array | IdentifiedArray |
|---|---|---|
| 요소 접근 (Index) | O(1) | O(1) |
| 요소 검색 (ID 기준) | O(n) | O(1) |
| 순서 보장 | 보장함 | 보장함 |
| ID 중복 허용 | 허용함 (직접 체크 필요) | 불허 (고유성 보장) |
| 안정성 | 인덱스 변경 시 위험함 | ID 기반이라 안전함 |
TCA에서 리스트 형태의 State를 관리할 때 IdentifiedArray는 거의 필수다. 부모 리듀서가 자식 리듀서의 상태를 식별하고 액션을 전달할 때, 인덱스가 아닌 ID를 사용해야만 리스트의 순서가 바뀌어도 정확한 타겟에 액션을 전달할 수 있기 때문이다.
struct ParentState {
// Array 대신 IdentifiedArray 사용
var items: IdentifiedArrayOf<ItemState> = []
}
SwiftUI의 ForEach는 Identifiable 데이터를 기반으로 뷰를 그린다. 이때 IdentifiedArray를 사용하면 특정 아이템의 상태가 변경되었을 때 전체 배열을 뒤지지 않고도 해당 요소를 즉시 찾아 업데이트할 수 있어 대규모 리스트에서 성능 이점을 얻을 수 있다.
서버에서 받아온 데이터를 로컬에 저장하거나 화면에 보여줄 때, 중복된 ID를 가진 데이터가 들어오는 것을 방지하고 싶다면 IdentifiedArray에 넣는 것만으로도 중복 체크 로직을 대신할 수 있다.
IdentifiedArray는 단순히 편리한 도구를 넘어, 대규모 데이터와 복잡한 상태 전환이 잦은 현대 iOS 앱 개발에서 성능과 안전성이라는 두 마리 토끼를 잡게 해주는 핵심 컬렉션이다.
인덱스 기반의 접근 때문에 Index out of range 에러로 밤을 지새워봤다면, 이제는 Array 대신 IdentifiedArray를 적극적으로 도입해보자. 코드가 훨씬 간결해지고 견고해지는 것을 체감할 수 있을 것이다.
Array로 돌아가기 힘들 정도로 편리하다. 특히 forEach 리듀서를 쓸 때의 쾌감은 이루 말할 수 없다.