Combine 中的 `reduce(into: [:])` 等效操作。

huangapple go评论59阅读模式
英文:

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]) -&gt; AnyPublisher&lt;[String: String], GenericError&gt; {
        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: &quot;Invalid deep link&quot;))
                .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 -&gt; AnyPublisher&lt;[String:String], GenericError&gt; in
                if(dictionary.isEmpty)
                {
                    return Fail(outputType: [String:String].self, failure: GenericError.with(message: &quot;Error parsing query Items (deep linking)&quot;))
                        .eraseToAnyPublisher()
                } else {
                    return Just(dictionary)
                        .setFailureType(to: GenericError.self)
                        .eraseToAnyPublisher()
                }
            }
            .eraseToAnyPublisher()
    }

Not sure if this is the best way but worked.

huangapple
  • 本文由 发表于 2023年2月6日 05:58:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/75355803.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定