如何将Typescript链式泛型函数转换为可使用的Swift实现
核心类型定义
首先对齐TS的Filter类型,Swift中定义如下:
// 对应TS的Filter<T>,入参为泛型对象,返回布尔值 typealias Filter<Root> = (Root) -> Bool
1. isKeyEqualToValue 实现
TS中用keyof T做键标识,Swift中对应使用KeyPath,同时因为要做相等判断,值类型需要遵守Equatable协议:
func isKeyEqualToValue<Root, Value: Equatable>(for keyPath: KeyPath<Root, Value>) -> (Value) -> Filter<Root> { return { targetValue in return { object in object[keyPath: keyPath] == targetValue } } }
调用示例
假设你有一个User结构体:
struct User { let id: Int let name: String } // 调用方法,对应TS的isKeyEqualToValue<User>('name')("张三") let nameIs张三 = isKeyEqualToValue(for: \User.name)("张三") // 使用过滤器 let testUser = User(id: 1, name: "张三") print(nameIs张三(testUser)) // 输出true
2. hasInArray 与 notInArray 实现
你当前写的版本存在两个问题:一是values.contains需要明确值的比较规则,二是要对齐TS中把值转成String判断包含的逻辑,或者如果你的场景确定值类型一致,可以直接约束Value为Equatable实现类型安全:
对齐原TS转String判断的版本(逻辑完全对齐)
func hasInArray<Root>(for keyPath: KeyPath<Root, some CustomStringConvertible>) -> ([Any]) -> Filter<Root> { return { values in return { object in let targetStr = String(describing: object[keyPath: keyPath]) return values.contains { String(describing: $0) == targetStr } } } } // 对应的notInArray实现 func notInArray<Root>(for keyPath: KeyPath<Root, some CustomStringConvertible>) -> ([Any]) -> Filter<Root> { return { values in return { object in let targetStr = String(describing: object[keyPath: keyPath]) return !values.contains { String(describing: $0) == targetStr } } } }
类型安全优化版本(推荐,避免运行时类型转换问题)
如果你的数组元素类型和字段类型一致,可以约束Value为Equatable,编译期就能检查类型匹配:
func hasInArray<Root, Value: Equatable>(for keyPath: KeyPath<Root, Value>) -> ([Value]) -> Filter<Root> { return { values in return { object in values.contains(object[keyPath: keyPath]) } } } func notInArray<Root, Value: Equatable>(for keyPath: KeyPath<Root, Value>) -> ([Value]) -> Filter<Root> { return { values in return { object in !values.contains(object[keyPath: keyPath]) } } }
业务场景配套实现
对应你代码中的isEvery(所有过滤器都满足)、isAny(任意一个过滤器满足)的实现:
// 所有过滤器都返回true时才返回true,对应TS的isEvery func isEvery<Root>(_ filters: [Filter<Root>]) -> Filter<Root> { return { object in filters.allSatisfy { $0(object) } } } // 任意一个过滤器返回true就返回true,对应TS的isAny func isAny<Root>(_ filters: [Filter<Root>]) -> Filter<Root> { return { object in filters.contains { $0(object) } } }
批量过滤示例
和你的业务逻辑对齐的Swift版本写法,时间复杂度为O(n)(n为待过滤数据总数),符合你规避O(n²)的需求:
// 假设buildAlertFilter是你自己实现的返回Filter<SomeType>的方法 let filters = userFilters.map { userFilterSet in isEvery(buildAlertFilter(userFilterSet)) } let isMatch = isAny(filters) // 批量过滤数据 let result = flow.reduce(into: [SomeType]()) { feed, obj in guard isMatch(obj) else { return } feed.append(obj) }
内容的提问来源于stack exchange,提问作者littleindianboy
相关产品推荐
相关产品推荐

