🔥 Set

729자
8분

Swift에서 Set은 같은 타입의 고유한 값들을 정의된 순서 없이 저장하는 컬렉션입니다. 항목의 순서가 중요하지 않거나, 한 항목이 한 번만 나타나도록 보장해야 할 때 배열 대신 set을 사용할 수 있죠.

Set 타입에 대한 해시 값

Set에 저장되려면 타입이 hashable해야 합니다. 즉, 타입 자체를 위한 hash value를 계산하는 방법을 제공해야 한다는 뜻이에요. 해시 값은 a == b이면 a의 해시 값이 b의 해시 값과 같도록, 동등하게 비교되는 모든 객체에 대해 동일한 Int 값입니다.

Swift의 모든 기본 타입(String, Int, Double, Bool 등)은 기본적으로 해시 가능하며, set 값 타입이나 딕셔너리 키 타입으로 사용될 수 있어요. 연관 값이 없는 열거형 case 값들도 기본적으로 해시 가능하답니다.

Set 타입 구문

Swift set의 타입은 Set<Element>로 작성되는데, 여기서 Element는 set이 저장할 수 있는 타입이에요. 배열과 달리 set은 동등한 축약 표기법이 없습니다.

빈 Set 생성 및 초기화

초기화 구문을 사용하여 특정 타입의 빈 set을 생성할 수 있어요:

var letters = Set<Character>()
print("letters is of type Set<Character> with \(letters.count) items.")
// "letters is of type Set<Character> with 0 items."을 출력합니다.
swift

또는 컨텍스트가 이미 함수 인자나 이미 타입이 지정된 변수 또는 상수와 같은 타입 정보를 제공하는 경우, 빈 배열 리터럴로 빈 set을 생성할 수 있습니다:

letters.insert("a")
// letters는 이제 Character 타입의 값 1개를 포함합니다.
letters = []
// letters는 이제 빈 set이지만, 여전히 Set<Character> 타입입니다.
swift

배열 리터럴로 Set 생성하기

배열 리터럴을 사용하여 set을 초기화할 수도 있는데, 이는 하나 이상의 값을 set 컬렉션으로 작성하는 간편한 방법이죠.

아래 예제는 String 값을 저장하기 위해 favoriteGenres라는 set을 생성합니다:

var favoriteGenres: Set<String> = ["Rock", "Classical", "Hip hop"]
// favoriteGenres는 세 개의 초기 항목으로 초기화되었습니다.
swift

favoriteGenres 변수는 "일련의 String 값"으로 선언되었고, Set<String>으로 작성되었어요. 이 특정 set은 String 값 타입을 지정했기 때문에 String 값만 저장할 수 있습니다. 여기서 favoriteGenres set은 배열 리터럴 내에 작성된 세 개의 String 값("Rock", "Classical", "Hip hop")으로 초기화됩니다.

Set 타입은 배열 리터럴만으로는 유추될 수 없으므로, Set 타입을 명시적으로 선언해야 해요. 그러나 Swift의 타입 추론 덕분에, 한 가지 타입의 값만 포함하는 배열 리터럴로 set을 초기화하는 경우에는 set의 요소 타입을 작성할 필요가 없습니다. favoriteGenres의 초기화는 대신 더 짧은 형식으로 작성될 수 있었을 거예요:

var favoriteGenres: Set = ["Rock", "Classical", "Hip hop"]
swift

배열 리터럴의 모든 값이 동일한 타입이기 때문에, Swift는 Set<String>favoriteGenres 변수에 사용할 올바른 타입임을 유추할 수 있습니다.

Set 접근 및 수정

메서드와 속성을 통해 set에 접근하고 수정할 수 있어요.

Set의 항목 수를 알아내려면 읽기 전용 count 속성을 확인하세요:

print("I have \(favoriteGenres.count) favorite music genres.")
// "I have 3 favorite music genres."를 출력합니다.
swift

count 속성이 0과 같은지 확인하는 지름길로 Boolean isEmpty 속성을 사용하세요:

if favoriteGenres.isEmpty {
    print("As far as music goes, I'm not picky.")
} else {
    print("I have particular music preferences.")
}
// "I have particular music preferences."를 출력합니다.
swift

Set의 insert(_:) 메서드를 호출하여 set에 새 항목을 추가할 수 있습니다:

favoriteGenres.insert("Jazz")
// favoriteGenres는 이제 4개의 항목을 포함합니다.
swift

Set의 remove(_:) 메서드를 호출하여 set에서 항목을 제거할 수 있는데, 이 메서드는 항목이 set의 멤버인 경우 해당 항목을 제거하고 제거된 값을 반환하거나, set이 해당 항목을 포함하지 않으면 nil을 반환합니다. 또는 set의 removeAll() 메서드로 set의 모든 항목을 제거할 수도 있어요.

if let removedGenre = favoriteGenres.remove("Rock") {
    print("\(removedGenre)? I'm over it.")
} else {
    print("I never much cared for that.")
}
// "Rock? I'm over it."을 출력합니다.
swift

Set이 특정 항목을 포함하는지 확인하려면 contains(_:) 메서드를 사용하세요.

if favoriteGenres.contains("Funk") {
    print("I get up on the good foot.")
} else {
    print("It's too funky in here.")
}
// "It's too funky in here."를 출력합니다.
swift

Set 반복

for-in 루프로 set의 값을 반복할 수 있습니다.

for genre in favoriteGenres {
    print("\(genre)")
}
// Classical
// Jazz
// Hip hop
swift

for-in 루프에 대한 자세한 내용은 For-In Loops를 참조하세요.

Swift의 Set 타입에는 정의된 순서가 없어요. 특정 순서로 set의 값을 반복하려면 sorted() 메서드를 사용하세요. 이 메서드는 < 연산자를 사용하여 정렬된 배열로 set의 요소를 반환합니다.

for genre in favoriteGenres.sorted() {
    print("\(genre)")
}
// Classical
// Hip hop
// Jazz
swift

이렇게 Set에 대해 자세히 알아보았는데요, 직접 Set을 만들어 보는 건 어떨까요? 아래와 같이 간단한 Set을 만들어 볼 수 있겠죠:

// 과일 Set 만들기
var fruits: Set = ["apple", "banana", "orange"]
 
// 과일 개수 출력
print("I have \(fruits.count) favorite fruits.")
// "I have 3 favorite fruits."를 출력합니다.
 
// "grape" 추가하기
fruits.insert("grape")
 
// Set 반복하며 과일 이름 출력하기
for fruit in fruits {
    print("\(fruit)")
}
// apple
// banana
// grape
// orange
 
// 알파벳 순서로 정렬하여 출력하기
for fruit in fruits.sorted() {
    print("\(fruit)")
}
// apple
// banana
// grape
// orange
swift