let numberSet = Set(1...11) let divideSet = numberSet.map({ $0 / 10 }) //Error: Set does not have a member named map :(
Swift 1.2支持Set()无序集合,但map(_:)似乎在Sets上不起作用,因此我决定在操场上变聪明并尝试:
Set()
map(_:)
let stringSet = Set(map(numberSet, { String($0)})) println(stringSet) stringSet = ["2", "11", "1", "8", "6", "4", "3", "9", "7", "10", "5]
这似乎有效。所以我尝试扩展Set:
extension Set { func map<U>(transform: (T) -> U) -> Set<U> { return Set(Swift.map(self, transform)) } } Error: "couldn't find initialiser for Set(T) that accepts argument of type U"
而且我认为有一个很好的理由为什么它不起作用,例如这里的示例:
let smarDividSet = Set(map(numberSet, {$0 / 2})) println(smarDividSet) smartDividSet = "[5, 0, 2, 4, 1, 3]” //Somehow elements is the Set are going missing.
关于如何扩展Set以可靠地使用map(_ :)的任何想法?谢谢大家
更新: Swift 2和3进行了很多更改。的通用占位符Set现在Element是T,而不是,并且所有集合都有一个map()返回 数组 的方法 。
Set
Element
T
map()
对于Set -> Set映射的问题(例如,将不同的元素映射到相同的结果)也给出了很好的论据。另一方面,可能会有这种映射的用例,因此这是 Swift 3 的更新(现在使用其他名称)。
Set -> Set
extension Set { func setmap<U>(transform: (Element) -> U) -> Set<U> { return Set<U>(self.lazy.map(transform)) } }
例:
let numberSet = Set(1...11) let divideSet = numberSet.setmap { $0 / 2 } print(divideSet) // [5, 0, 2, 4, 1, 3]
(旧答案:) 您快到了。由于某些原因,必须显式指定返回集的通用类型:
extension Set { func map<U>(transform: (T) -> U) -> Set<U> { return Set<U>(Swift.map(self, transform)) } }
let numberSet = Set(1...11) let divideSet = numberSet.map { $0 / 2 } println(divideSet) // [5, 0, 2, 4, 1, 3]
由于整数除法会$0 / 2 截断 商,因此结果集中的元素较少 ,例如4/2和5/2都映射到同一元素2。对于浮点除法不会发生这种情况:
$0 / 2
let floatdivideSet = numberSet.map { Double($0) / 2.0 } println(floatdivideSet) // [4.0, 5.0, 4.5, 5.5, 2.0, 3.0, 3.5, 2.5, 1.5, 1.0, 0.5]
另一个可能的实现是
extension Set { func map<U>(transform: (T) -> U) -> Set<U> { return Set<U>(lazy(self).map(transform)) } }
在此lazy(self)返回LazyForwardCollection具有map()方法的,并LazyForwardCollection再次返回。优点可能是不创建任何中间数组。
lazy(self)
LazyForwardCollection