Section 7/161 menit
7. Operator Transformasi dan Filtering
7. Operator Transformasi dan Filtering
compacted
Menghapus nil dari sequence optional — versi async dari compactMap { $0 }.
swift
// compacted: hilangkan nil dari stream
let rawValues: AsyncStream<Int?> = ... // mungkin ada nil
for await value in rawValues.compacted() {
// value dijamin non-nil di sini
process(value) // value: Int, bukan Int?
}
// Ekuivalen tapi lebih ekspresif dari:
for await value in rawValues.compactMap({ $0 }) {
process(value)
}
removeDuplicates
Menghapus elemen berturut-turut yang sama — tidak menyimpan history semua elemen, hanya membandingkan dengan elemen sebelumnya.
swift
// removeDuplicates: hanya teruskan jika berbeda dari sebelumnya
let connectionState: AsyncStream<ConnectionState> = ...
for await state in connectionState.removeDuplicates() {
// Tidak akan dapat .connected dua kali berturut-turut
// Berguna untuk menghindari update UI yang tidak perlu
updateConnectionIndicator(state)
}
// Dengan custom comparator
for await user in userStream.removeDuplicates(by: { $0.id == $1.id }) {
// Hanya update jika ID berubah (bukan hanya reference)
updateProfile(user)
}
adjacentPairs
Menghasilkan tuple dari dua elemen berturutan — berguna untuk menghitung selisih atau perubahan.
swift
// adjacentPairs: bandingkan nilai sekarang dengan sebelumnya
let stockPrices: AsyncStream<Double> = ...
for await (previous, current) in stockPrices.adjacentPairs() {
let change = current - previous
let percentChange = (change / previous) * 100
print("Perubahan: \(String(format: "%.2f", percentChange))%")
if abs(percentChange) > 5 {
await sendAlert("Perubahan signifikan: \(percentChange)%")
}
}
reductions
Versi async dari scan di Combine — menghasilkan nilai intermediate dari operasi reduce yang berjalan.
swift
// reductions: akumulasi running total
let transactions: AsyncStream<Double> = ...
for await runningTotal in transactions.reductions(0, +) {
// emit: 100, 150, 220, 180, ... (running total setelah setiap transaksi)
updateBalanceDisplay(runningTotal)
}
// reductions dengan initial value terpisah
for await stats in sensorReadings.reductions(into: SensorStats()) { stats, reading in
stats.count += 1
stats.sum += reading.value
stats.min = min(stats.min, reading.value)
stats.max = max(stats.max, reading.value)
} {
updateStatsDisplay(stats)
}
interspersed
Menyisipkan elemen di antara setiap elemen sequence.
swift
// interspersed: sisipkan separator
let words = ["Swift", "adalah", "bahasa", "modern"].async
for await word in words.interspersed(with: " ") {
print(word, terminator: "")
// Output: "Swift adalah bahasa modern"
}
// Berguna untuk separator UI (divider antar item)
let items = itemStream.interspersed(with: .divider)