본문 바로가기
Apple/Swift

[Swift] 배열에서 중복 제거하기

by 어멘드 2022. 2. 5.
반응형

Set 사용

 Set의 성질을 이용한다. 집합 내에는 중복 원소가 존재하지 않으므로, 간단하게 Array를 가지고 집합 Set을 생성하면 중복이 제거된다.


Array를 Set으로

 Set의 이니셜 라이저 중에 Sequence를 받아 Set을 만들어주는 것이 있다. Array도 Sequence 프로토콜을 준수하므로 이것을 사용하면 된다.

init<Source>(_ sequence: Source) where Element == Source.Element, Source : Sequence

예시 코드

 중복이 포함된 Array<Int>을 가지고 Set<Int>를 만드는 코드이다. 중복되는 원소들이 제거되고 1, 2, 3, 4, 5만 남은 것을 확인할 수 있다.

 단, Set은 원소들 간 순서가 없는 unordered collection이기 때문에 배열의 순서를 유지할 수는 없다.

let duplicateExists = [1, 2, 2, 1, 3, 5, 5, 1, 1, 4]
let duplicateRemoved = Set(duplicateExists)     // [3, 2, 4, 5, 1]

커스텀 타입

 커스텀 타입 배열인 경우 주의할 점이 있다. Set 공식문서를 보면, Hashable 프로토콜을 채택한 타입만 요소가 될 수 있다. 따라서 커스텀 타입이라면, Hashable 프로토콜을 채택해주어야 해당 타입의 Set을 만들 수가 있다.

@frozen struct Set<Element> where Element : Hashable

 

 아래와 같이 Person 타입을 만들고 Person 배열로 Set을 만드려고 하니 Referencing initializer 'init(_:)' on 'Set' requires that 'Person' conform to 'Hashable' 에러가 발생한다.

struct Person {
    let name: String
    let age: Int
}

let duplicateExist = [Person(name: "Tom", age: 13), Person(name: "Tom", age: 13), Person(name: "Jenny", age: 21)]
let duplicateRemoved = Set(duplicateExist)
// Referencing initializer 'init(_:)' on 'Set' requires that 'Person' conform to 'Hashable'

 

 Person 타입에 Hashable 프로토콜을 채택해주면 아래와 같이 중복된 Person(name: "Tom", age: 13)이 잘 제거된다.

struct Person: Hashable {
    let name: String
    let age: Int
}

let duplicateExist = [Person(name: "Tom", age: 13), Person(name: "Tom", age: 13), Person(name: "Jenny", age: 21)]
let duplicateRemoved = Set(duplicateExist)  // [(Tom, 13), (Jenny, 21)]
반응형

댓글