티스토리 뷰

반응형

 

안녕하세요 :) Zedd입니다.

오늘은 요소를 필터링 하는 Combine Operator친구들을 공부해봅시다.

Mapping Elements Operator 읽으러가기 

 

Combine ) Operator (1) - Mapping Elements

안녕하세요 :) Zedd입니다. 요즘 너무 정신이 없네요 ㅠㅜ!!!!!!! 오늘부터 컴바인 오퍼레이터를 빠개볼거에요~~ 오퍼레이터 일단 ㄱㅐ많은데..같은 섹션에 있는 친구들을 보다보면.. 언젠가...다 볼

zeddios.tistory.com

 

그럼 시작!

 

filter

tryFilter

compactMap

tryCompactMap

removeDuplicates

removeDuplicates(by: )

tryRemoveDuplicates(by: )

replaceEmpty(with: )

replaceError(with: )

 

이렇게 있네요. 크게 어려워보이는건 없네요..!?

시작해봅시다.

 

filter

필터는 제공된 closure와 일치하는(match) 모든 요소를 다시(re) publish합니다.

그냥 Swift Standard Library에 있는거랑 똑같다고 보면 될 듯..!

제공된 closure에서 2로 나누어 떨어지냐와 일치하는 친구들만 publish되는겁니다.

그래서 2와 4가 나왔죠!

 

tryFilter

앞에 try가 붙으면 에러를 던질 수 있는 closure를 넣을 수 있다...라고 보심 될듯.

만약 요소가 0이면 DivisionByZeroError를 내고, 아니면 2로 나눠서 떨어지는것만 필터링 합니다.

당연히..에러가 나면 스트림이 실패하고 종료되겠죠? 

 

compactMap

Combine의 compactMap역시 Swift Standard Library에 있는 친구와 비슷합니다.

compactMap은 publisher 스트림에 nil을 제거하고, nil이 아닌 요소만 다운스트림에 publish하는 친구에요.

애플 예제입니다.

배열이 있습니다. [0, 1, 2, 3, 4, 5]

romanNumeralDict[0].-> 딕셔너리 안에 없음 -> nil

romanNumeralDict[1].-> 딕셔너리 안에 있음 -> "I"

romanNumeralDict[2].-> 딕셔너리 안에 있음 -> "II"

romanNumeralDict[3].-> 딕셔너리 안에 있음 -> "III"

romanNumeralDict[4].-> 딕셔너리 안에 있음 -> nil

romanNumeralDict[5].-> 딕셔너리 안에 있음 -> "V"

 

compactMap이 nil인 요소를 제거하고 다운스트림으로 내려주니까 sink에서는 

// Prints: "I II III V"

이런 결과를 얻을 수 있죠.

 

tryCompactMap

이제 걍 알겠죠

closure에서 에러 던질 수 있겠군..

애플 예제 입니다.

tryCompactMap안에서 에러를 던질 수 있는 함수를 호출했죠! 

배열이 있습니다. [6, 5, 4, 3, 2, 1, 0]

romanNumeralDict[6].-> 딕셔너리 안에 없음 -> nil

romanNumeralDict[5].-> 딕셔너리 안에 있음 -> "V"

romanNumeralDict[4].-> 딕셔너리 안에 있음 -> "IV"

romanNumeralDict[3].-> 딕셔너리 안에 있음 -> "III"

romanNumeralDict[2].-> 딕셔너리 안에 있음 -> "II"

romanNumeralDict[1].-> 딕셔너리 안에 있음 -> "I"

romanNumeralDict[0].-> romanNumeral메소드의 guard에서 걸러짐 -> ParseError 에러 던짐 

-> 실패 ->  스트림 실패로 종료. 

입니다.

 

removeDuplicates

이전 요소와 일치하지 않는 것만 publish하는 친구입니다.

이전 요소와 일치하지 않는 것!!!!!만 생각하면 됩니다.

2다음에 2가 들어와서 publish하지 않은거고, 3다음에도 3, 3이 4 다음에도 4, 4, 4가 들어와서 publish하지 않은겁니다.

4와 0은 서로 다른 요소니까 0을 publish한거에요/

removeDuplicates operator에는 two-element memory가 있다고 해요.

이 operator는 현재 및 이전에 publish된 요소를 비교의 기초로 사용한다고 합니다!

 

removeDuplicates(by: )

이건 제공된 closure에서 평가한대로 이전 요소와 일치하지 않는 요소만 publish하는겁니다.

closure는 두 요소가 동일한지 여부를 평가하기 위함이에요.

여기서 true가 리턴되면 두번째 요소가 첫번째 요소와 duplicate(중복)임을 나타내는거에요.

이렇게!

그럼 x좌표가 같은 것이 연속으로 나오면 그것들은 다 무시되겠죠?!

 

tryRemoveDuplicates(by: )

removeDuplicates에 try가 붙었으니 모다..? closure안에서 에러를 던질 수 이따!?!?

역시나 다른 try친구들과 마찬가지로 closure안에서 오류가 발생하면 publisher는 throw된 오류와 함께 종료됩니다.

위에서 첫번째 요소 그러니까 이전요소가 4이고 현재 요소가 4이면 Error를 던지게 했죠!?

그래서 출력에서 첫번째 4는 출력이되고 그 다음 4에서 에러가 나게 됩니다.

그리고 에러가 발생했으니 스트림이 종료되구요!!

 

RemoveDuplicates의 동작을...잠깐..! 살펴보면,

[0, 0, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4]로 예를 들어볼개ㅔ요.

 

value: 0

========

first: 0

second: 0

duplicate!

========

first: 0

second: 1

value: 1

========

first: 1

second: 2

value: 2

========

first: 2

second: 2

duplicate!

========

first: 2

second: 3

value: 3

========

first: 3

second: 3

duplicate!

========

first: 3

second: 3

duplicate!

========

first: 3

second: 4

value: 4

========

first: 4

second: 4

duplicate!

========

first: 4

second: 4

duplicate!

========

first: 4

second: 4

duplicate!

========

finished

 

대충 이런식입니다. 

제일 처음에는 closure를 안타고 바로 sink로 가는것을 볼 수 있죠. 이걸 그냥 보여드리고 싶었음ㅋ

 

replaceEmpty(with: )

그냥 이름만 봐도 뭔지 알 수 있죠,,, 빈 스트림을 제공된 요소로 바꾸는 친구입니다.

numbers배열이 비어있으니, Double.nan으로 채워준것을 볼 수 있죠!.

참고로 numbers배열이 비어있지 않으면;; replaceEmpty는 아무 영향을 주지 않습니다.

그리고 배열이 비어있으니 [Double.nan, Double.pi]이렇게 배열로 replcae해주고싶다!!!는 안됩니다.

publisher의 Element타입을 넣어줘야합니다. [Element]가 아니라요

 

replaceError(with: )

이것도 이름만 봐도;;알 수 있음

ㅇㅔ러를 제공된 요소로 바꾸겠다 입니다.

애플 예제도 좋긴한데..그냥 tryRemoveDuplicates에서 쓴 예제를 좀 고쳐봤어요.

first와 second가 같으면 BadValuesError를 내게 되는데, 그 에러를 replaceError에서 10000으로 고쳐줬습니다.

(당연히 publisher의 Element타입과 같은걸 넣어줘야합니다! 위 예제에서 막 String이런거 넣어주면 안됨.)

아까는 에러로 스트림이 종료되게 됐는데, 지금은 정상적으로 종료된 것을 볼 수 있죠. 

replaceError는 single replacement element를 전송하고 오류를 처리하려는 경우에 유용해요.

그게 아니라면 catch(_ :)를 사용해서 오류를 복구하고 대체 publisher를 제공하는게 좋다고 합니다.

 

Filtering Elements은 이렇게 끝입니다..! 벌써 헷갈리는 군요..

 

다음 글 읽으러가기

 

Combine ) Operator (3) - Reducing Elements

안녕하세요 :) Zedd입니다. Operator (1) - Mapping Elements Operator (2) - Filtering Elements 3번째 Reducing Elements 섹션입니다. collect() collect(_:) collect(_:options:) ignoreOutput() reduce(_:_:..

zeddios.tistory.com

 

반응형