为Equatable元组数组扩展方法以查找首个匹配元组
给包含Equatable元组的数组扩展contains方法
其实这个需求完全可以实现,核心是利用Swift对元组的特殊处理——当元组的所有元素都遵守Equatable时,Swift会自动为这个元组生成==运算符,我们只需要针对不同长度的元组给Array写对应的扩展即可。
针对2元素元组的扩展
先从最常用的2元素元组开始,我们可以这样写:
extension Array where Element == (T, U), T: Equatable, U: Equatable { func contains(_ target: Element) -> Bool { return self.contains { $0 == target } } }
针对3元素元组的扩展
如果需要支持3元素元组,只需要复制上面的结构,增加一个泛型参数:
extension Array where Element == (T, U, V), T: Equatable, U: Equatable, V: Equatable { func contains(_ target: Element) -> Bool { return self.contains { $0 == target } } }
更多长度的元组
同理,如果你需要支持4元素、5元素的元组,只需要按照同样的模式添加扩展,每多一个元素就增加一个对应的泛型参数并约束它遵守Equatable。
测试示例
写好扩展后,调用起来就和数组原生的contains方法一样自然:
// 测试2元素元组数组 let pairArray = [(1, "apple"), (2, "banana"), (3, "cherry")] print(pairArray.contains((2, "banana"))) // 输出 true print(pairArray.contains((4, "date"))) // 输出 false // 测试3元素元组数组 let tripleArray = [(1, "red", true), (2, "blue", false)] print(tripleArray.contains((2, "blue", false))) // 输出 true
为什么不能写一个通用的扩展?
这是因为Swift的类型系统里,不同长度的元组是完全不同的类型(比如(Int, String)和(Int, String, Bool)是两种毫不相关的类型),所以没办法用一个扩展覆盖所有长度的元组,只能针对每种长度单独处理。
这种扩展方式比自由函数更符合Swift的API设计风格,调用时的体验也更流畅~
内容的提问来源于stack exchange,提问作者Cristik
相关产品推荐
相关产品推荐

