You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 09:36:02