This repository has been archived on 2026-02-12. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
swift-duct-calc/Sources/DatabaseClient/Internal/Sequence+asyncMap.swift
2026-02-04 21:06:05 -05:00

42 lines
1.1 KiB
Swift

import Foundation
extension Sequence {
// Taken from: https://forums.swift.org/t/are-there-any-kind-of-asyncmap-method-for-a-normal-sequence/77354/7
func asyncMap<Result: Sendable>(
_ transform: @escaping @Sendable (Element) async throws -> Result
) async rethrows -> [Result] where Element: Sendable {
try await withThrowingTaskGroup(of: (Int, Result).self) { group in
var i = 0
var iterator = self.makeIterator()
var results = [Result?]()
results.reserveCapacity(underestimatedCount)
func submitTask() throws {
try Task.checkCancellation()
if let element = iterator.next() {
results.append(nil)
group.addTask { [i] in try await (i, transform(element)) }
i += 1
}
}
// Add initial tasks
for _ in 0..<ProcessInfo.processInfo.processorCount {
try submitTask()
}
// Submit more tasks as results complete
while let (index, result) = try await group.next() {
results[index] = result
try submitTask()
}
return results.compactMap { $0 }
}
}
}