var subscriptions = Set<AnyCancellable>()
example(of: "mapping key paths") {
let publisher = PassthroughSubject<Coordinate, Never>()
publisher
.map(\.x, \.y) // Keypath
.sink(receiveValue: { x, y in
print("좌표 (\(x), \(y)) 는", quadrantOf(x: x, y: y), "사분면 입니다.")
})
.store(in: &subscriptions)
publisher.send(Coordinate(x: 10, y: -8))
publisher.send(Coordinate(x: 0, y: 5))
}
/*
——— Example of: mapping key paths ———
좌표 (10, -8) 는 4 사분면 입니다.
좌표 (0, 5) 는 boundary(경계선) 사분면 입니다.
*/
tryMap(_:)
error throw를 tryMap을 사용해서 error downstream을 방출합니다.
아래는 존재하지 않는 디렉토리 이름을 설정해 에러를 내보는 예시 입니다.
var subscriptions = Set<AnyCancellable>()
example(of: "tryMap") {
Just("Directory name that does not exist")
.tryMap { try FileManager.default.contentsOfDirectory(atPath: $0) }
.sink(receiveCompletion: { print($0) }, receiveValue: { print($0) })
.store(in: &subscriptions)
}
/*
——— Example of: tryMap ———
failure(Error Domain=NSCocoaErrorDomain Code=260 "The folder “Directory name that does not exist” doesn’t exist." UserInfo={NSUserStringVariant=(
Folder
), NSFilePath=Directory name that does not exist, NSUnderlyingError=0x6000030ea130 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}})
*/
Flattening publishers
flatMap(maxPublishers:_:)
여러개의 publisher upstream -> single downstream으로 변환 해줍니다.
1. Convert the input to numbers — use the convert function, which will return nil if it cannot convert the input to an integer.
-> input을 숫자로 변환 — input을 정수로 변환할 수 없는 경우 nil을 반환하는 convert 함수를 사용합니다.
2. If the previous operator returns nil, replace it with a 0.
-> 이전 연산자가 nil을 반환하면 0으로 바꿉니다.
3. Collect ten values at a time, which correspond to the three-digit area code and seven-digit phone number format used in the United States.
-> 미국에서 사용되는 3자리 지역 코드 및 7자리 전화번호 형식에 해당하는 10개의 값을 한 번에 수집(collect)합니다.
4. Format the collected string value to match the format of the phone numbers in the contacts dictionary — use the provided format function.
-> contacts에 있는 전화번호의 형식과 일치하도록 수집된 문자열 값의 형식을 지정합니다. 제공된 형식 기능을 사용합니다.
5. “Dial” the input received from the previous operator — use the provided dial function.
-> 이전 연산자로부터 받은 input "다이얼" - 제공된 다이얼 기능을 사용합니다.
input
.map(convert) // String -> Int 변환 >> (문자입력시) keyMap을 통해 문자에 포함되는 숫자로 변환
.replaceNil(with: 0) // Optional 바인딩 처리 후, 변환할 수 없는것 (nil) -> 0으로 대체
.collect(10) // 한 배열에 10개 요소 담기
.map(format) // Int -> String >> String 통합 >> 인덱스 3번째, 7번째 자리에 "-" 추가
.map(dial) // contacts[phoneNumber] 키 값으로 접근해 value(사람이름) 반환
.sink(receiveCompletion: { print($0) },
receiveValue: { print($0) })
/*
——— Example of: Create a phone number lookup ———
Contact not found for 000-123-4567
Dialing Marin (408-555-4321)...
Dialing Shai (212-555-3434)...
*/
배운것
1. 함수안에 함수를 사용할때 소괄호로 호출을 따로 안해줘도 된다. (예 - .map(convert))
-> 일급객체기 때문
2. 연속해서 함수의 조합들을 이용해 구현하는 방법이 꽤 직관적이고 코드가 간결해져 좋았다. 함수형 프로그래밍 체험한듯