英文:
reduce(into: [:]) equivalent for Combine in Swift
问题
在Combine中,用于替代reduce(into:)
的操作符是map
。
英文:
I've been struggling to find an equivalent for reduce(into:_:) in Combine.
enum GenericError : Error {
case with(message: String)
}
class Constants {
fileprivate static let scheme = "sampleScheme"
fileprivate static let host = "com.sampleHost"
fileprivate static let authPath = "/auth"
static let authQuery = "key"
}
func parse(_ url: URL, queryPathsFilterByKey: [String]) throws -> [String: String] {
guard url.scheme == Constants.scheme,
url.host == Constants.host,
url.path == Constants.authPath,
let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: true),
let queryItems = urlComponents.queryItems else {
throw GenericError.with(message: "Invalid deep link.")
}
// Create a [String:String] from [UrlQueryItems]
let query = queryItems.reduce(into: [:]) { result, item in
result[item.name] = item.value
}
let result = query.filter { queryPathsFilterByKey.contains($0.key) }
guard !result.isEmpty else {
throw GenericError.with(message: "Error parsing query Items (deep linking)")
}
return result
}
what operator replaces reduce(into:) in Combine?
答案1
得分: 0
func parse(_ url: URL, queryPaths: [String]) -> AnyPublisher<[String: String], GenericError> {
guard url.scheme == Constants.scheme,
url.host == Constants.host,
url.path == Constants.authPath,
let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: true),
let queryItems = urlComponents.queryItems else {
return Fail(outputType: [String:String].self, failure: GenericError.with(message: "Invalid deep link"))
.eraseToAnyPublisher()
}
return queryItems
.publisher
.reduce ([String:String]()) { dictionary, value in
var dict = dictionary
dict[value.name] = value.value
return dict
}
.filter { $0.allSatisfy { queryPaths.contains($0.key) } }
.flatMap { dictionary -> AnyPublisher<[String:String], GenericError> in
if(dictionary.isEmpty)
{
return Fail(outputType: [String:String].self, failure: GenericError.with(message: "Error parsing query Items (deep linking)"))
.eraseToAnyPublisher()
} else {
return Just(dictionary)
.setFailureType(to: GenericError.self)
.eraseToAnyPublisher()
}
}
.eraseToAnyPublisher()
}
Not sure if this is the best way but worked.
英文:
Found a way to do this
func parse(_ url: URL, queryPaths: [String]) -> AnyPublisher<[String: String], GenericError> {
guard url.scheme == Constants.scheme,
url.host == Constants.host,
url.path == Constants.authPath,
let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: true),
let queryItems = urlComponents.queryItems else {
return Fail(outputType: [String:String].self, failure: GenericError.with(message: "Invalid deep link"))
.eraseToAnyPublisher()
}
return queryItems
.publisher
.reduce ([String:String]()) { dictionary, value in
var dict = dictionary
dict[value.name] = value.value
return dict
}
.filter { $0.allSatisfy { queryPaths.contains($0.key) } }
.flatMap { dictionary -> AnyPublisher<[String:String], GenericError> in
if(dictionary.isEmpty)
{
return Fail(outputType: [String:String].self, failure: GenericError.with(message: "Error parsing query Items (deep linking)"))
.eraseToAnyPublisher()
} else {
return Just(dictionary)
.setFailureType(to: GenericError.self)
.eraseToAnyPublisher()
}
}
.eraseToAnyPublisher()
}
Not sure if this is the best way but worked.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论