🌾

[Swift] [Combine] ストリームに reduce() 処理の途中経過を流したい場合 -> scan() を使おう!

2022/02/05に公開

reduce() の復習

reduce() は以下のように、配列の数値を合計するときなどで使用されます。

let sum = [1, 2, 3, 4].reduce(0) { $0 + $1 }
print("sum: \(sum)") // sum: 10

この計算の過程を Combine のストリームで出力として流したい時に scan() を使うと簡単に書くことができます。

scan() を使ってみる

scan() の使い方は reduce() の使い方とかなり似ています。

以下が例になります。

var cancellables = Set<AnyCancellable>()

[1, 2, 3, 4].publisher
    .scan(0) { $0 + $1 }
    .sink {
        print("result: \($0)")
    } receiveValue: {
        print("output: \($0)")
    }
    .store(in: &cancellables)

// 出力
// output: 1 ← 0 + 1
// output: 3 ← 1 + 2
// output: 6 ← 3 + 3
// output: 10 ← 6 + 4
// result: finished

他に例を挙げると以下のようなこともできます。

[1, 2, 3, 4].publisher
    .scan([]) { $0 + [$1] }
    .sink {
        print("result: \($0)")
    } receiveValue: {
        print("output: \($0)")
    }
    .store(in: &cancellables)

// 出力
// output: [1]
// output: [1, 2]
// output: [1, 2, 3]
// output: [1, 2, 3, 4]
// result: finished

以上になります。

GitHubで編集を提案

Discussion