본문 바로가기
💡 Today I Learned/스터디 자료정리

[스터디2일차][RxSwift] 연산자

by 솔비님 2024. 10. 11.

 

1.  결합 연산자(Combine)

여러 Observable을 결합하여 하나의 Observable로 만듦

 

 

1-1.  merge

  • 여러 Observable을 병합하여 하나의 Observable로 결합
  • 각 Observable은 독립적으로 동작하며 값이 발생하는 즉시 병합되어 방출된다(순번X)

  • 활용 예시
let observable1 = Observable.of(1, 2, 3)
let observable2 = Observable.of(4, 5, 6)

Observable.merge(observable1, observable2)
    .subscribe(onNext: { value in
        print(value)
    })
    
//방출되는 순서에 따라 1, 2, 3, 4, 5, 6 또는 다른 순서일 수 있다

 

 

 

1-2.  concat

  • 여러 Observable을 순차적으로 결합
  • 첫 번째 Observable의 모든 값을 방출하고 완료된 후에 두 번째 Observable의 값을 방출
    (첫 번째 Observable이 완료되기 전에는 두 번째 Observable은 값을 방출하지 않는다)

 

  • 활용 예시
let observable1 = Observable.of(1, 2, 3)
let observable2 = Observable.of(4, 5, 6)

Observable.concat([observable1, observable2])
    .subscribe(onNext: { value in
        print(value)
    })

//1, 2, 3, 4, 5, 6

 

 

💡 merge와 concat의 차이점

- merge는 여러 Observable의 값을 방출 시점에 따라 동시다발적으로 병합한다(순서가 보장되지 않는다)
- concet은 여러 Observable을 순차적으로 결합하여 순서대로 방출한다(순서가 보장된다)

 

 

 

1-3.  combineLatest

  • 여러 Observable의 최신 값을 결합하여 새로운 Observable을 생성
  • Observable이 각각의 값을 방출할 때 마다 최신 값을 조합하여 방출한다
    (각 Observable이 최소한 하나의 값을 방출해야 동작한다)

 

  • 활용 예시
let observable1 = Observable.of(1, 2, 3)
let observable2 = Observable.of("A", "B", "C")

Observable.combineLatest(observable1, observable2) { value1, value2 in
    return "\(value1) and \(value2)"
}
.subscribe(onNext: { combinedValue in
    print(combinedValue)
})

//"1 and A", "2 and B", "3 and C"

 

 

 

1-4.  zip

  • Observable 값들을 순서대로 쌍으로 결합하여 방출하며 순서가 보장됨
  • Observable의 값이 준비되지 않으면 다른 Observable이 기다린다

  • 활용 예시
let letters = Observable.of("A", "B", "C")
let numbers = Observable.of(1, 2, 3)

Observable.zip(letters, numbers) { letter, number in
    return "\(letter) - \(number)"
}
.subscribe(onNext: { Value in
    print(zippedValue)
})

//"A - 1", "B - 2", "C - 3"

 

 

💡 combineLatest와 zip의 차이점

- combineLatest는 가장 최근에 방출한 값을 결합한다(최신 값 보장)
- zip은 Observable의 순서에 따라 1:1 결합한다(순서 유지)

 

 

 


2.  변환 연산자(Transeform)

방출되는 값을 특정 로직에 따라 변환하거나, 다른 Observable로 변환하여 데이터를 처리한다

 

 

2-1.  map

  • Observable에서 방출된 각 item을 특정 로직에 따라 독립적으로 변환한 후 새로운 Observable을 통해 방출
  • 기존의 값을 다른 형태나 형식으로 변경함(Swift의 map함수와 유사하게 동작)

  • 활용 예시
let numbers = Observable.of(1, 2, 3, 4, 5)

numbers.map { $0 * 2 }
    .subscribe(onNext: { value in
        print(value)
    })
    
//2, 4, 6, 8, 10

 

 

 

2-2.  flatMap

  • Observable에서 방출된 각 값을 또 다른 Observable로 변환하고, 변환된 Observable에서 방출한 값을 또 다시 병합하여 최종적으로 하나의 Observable을 생성한다
  • 주로 비동기 작업 또는 네트워크 요청, 데이터베이스 조회와 같은 작업에서 사용된다

  • 활용 예시
let userIds = Observable.of(1, 2, 3)

userIds.flatMap { id in
    return fetchUserData(for: id) // 가상의 비동기 네트워크 요청 메서드
}
.subscribe(onNext: { userData in
    print("User Data: \(userData)")
})

 

 

 

2-3.  flatMapLatest

  • 이전에 생성된 Observable이 아직 완료되지 않더라도 새로운 값이 방출되면 이전 Observable을 취소하고 새 값에 대한 Observable을 방출한다
    (가장 최근에 방출된 Observable의 값만 처리한다)
  • 주로 사용자 입력과 같은 최신값을 유지할 때 사용된다

  • 활용 예시
let searchText = Observable.of("Rx", "RxSwift", "RxSwift Operators")

searchText.flatMapLatest { query in
    return performSearch(query: query) // 가상의 검색 함수
}
.subscribe(onNext: { results in
    print("Search Results: \(results)")
})

 

 

 


3.  필터링 연산자(Filter)

Observable에서 방출된 값들 중 특정 조건에 해당하는 값만 방출하도록 필터링

 

 

3-1.  filter

  • 조건을 설정하여 불필요한 데이터를 걸러냄
  • 주로 유효성 검사, 데이터 필터링 등 사용

  • 활용 예시
let numbers = Observable.of(1, 2, 3, 4, 5, 6)

numbers.filter { $0 % 2 == 0 }
    .subscribe(onNext: { value in
        print(value)
    })
    
    //2, 4, 6

 

 

 

3-2.  distinctUntilChanged

  • Observable에서 연속적으로 동일한 값이 방출될 경우 중복 값을 필터링한다
  • 상태 변화가 필요할 때 유용하다(UI 업데이트 등)

  • 활용 예시
let values = Observable.of(1, 1, 2, 2, 3, 3, 4)

values.distinctUntilChanged()
    .subscribe(onNext: { value in
        print(value)
    })
    
//1, 2, 3, 4