Ble*_*pes 13 swift swift-extensions
let numberSet = Set(1...11)
let divideSet = numberSet.map({ $0 / 10 })
//Error: Set does not have a member named map :(
Run Code Online (Sandbox Code Playgroud)
Swift 1.2支持Set()
无序集合,但map(_:)
似乎不适用于集合,所以我决定在我的操场上变聪明并尝试:
let stringSet = Set(map(numberSet, { String($0)}))
println(stringSet)
stringSet = ["2", "11", "1", "8", "6", "4", "3", "9", "7", "10", "5]
Run Code Online (Sandbox Code Playgroud)
这似乎有效.所以我尝试扩展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"
Run Code Online (Sandbox Code Playgroud)
我认为它有一个很好的理由,它不起作用,就像这个例子:
let smarDividSet = Set(map(numberSet, {$0 / 2}))
println(smarDividSet)
smartDividSet = "[5, 0, 2, 4, 1, 3]”
//Somehow elements is the Set are going missing.
Run Code Online (Sandbox Code Playgroud)
关于如何将Set扩展为可靠地使用map(_ :)的任何想法?谢谢你们.
Mar*_*n R 14
更新:相当多的与斯威夫特2和3的通用占位改变Set
,现在Element
不是T
,所有的收藏有一个map()
返回的方法数组.
关于Set -> Set
映射问题(例如映射到相同结果的不同元素)也有很好的论据.另一方面,可能存在这种映射的用例,因此这里是Swift 3的更新(现在使用不同的名称).
extension Set {
func setmap<U>(transform: (Element) -> U) -> Set<U> {
return Set<U>(self.lazy.map(transform))
}
}
Run Code Online (Sandbox Code Playgroud)
例:
let numberSet = Set(1...11)
let divideSet = numberSet.setmap { $0 / 2 }
print(divideSet) // [5, 0, 2, 4, 1, 3]
Run Code Online (Sandbox Code Playgroud)
(老答案:)你几乎就在那里.由于某种原因,必须明确指定返回集的泛型类型:
extension Set {
func map<U>(transform: (T) -> U) -> Set<U> {
return Set<U>(Swift.map(self, transform))
}
}
Run Code Online (Sandbox Code Playgroud)
例:
let numberSet = Set(1...11)
let divideSet = numberSet.map { $0 / 2 }
println(divideSet) // [5, 0, 2, 4, 1, 3]
Run Code Online (Sandbox Code Playgroud)
结果集具有较少的元素,因为整数除法
$0 / 2
截断商,例如4/2和5/2都映射到相同的元素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]
Run Code Online (Sandbox Code Playgroud)
另一种可能的实现是
extension Set {
func map<U>(transform: (T) -> U) -> Set<U> {
return Set<U>(lazy(self).map(transform))
}
}
Run Code Online (Sandbox Code Playgroud)
这里lazy(self)
返回一个LazyForwardCollection
有map()
方法并LazyForwardCollection
再次返回的方法.优点可能是没有创建中间数组.
问题Set.map(_:)
是相同的Dictionary.map(_:)
,并且他们没有在Swift
模块(标准库)中实现它,因为实际上没有正确的方法来实现它.原因是:map
ping不只是枚举(你可以用a中的任何SequenceType
一个来做for-in
),但它正在将每个值转换(使用参数闭包)到另一个值.所以你会期望结果会包含所有transform(element)
内容,但是猜猜看,如果值相同则会崩溃(对于Dictionary
s,只有键的行为是这样的).
例如(提议的实施)
Set([1, 2, 3, 4, 5]).map { 1 }.count == 1
这也是为什么Swift.map
返回一个Array
而不是与参数相同SequenceType
/ CollectionType
传递的类型的原因source
.
稍微偏离,Dictionary
(如前所述)在键值上有相同的问题(基本上是a Set
),所以任何map
在Set<K>
或Set<(K, V)>
不能确保一致的映射,但只改变值的是好.这不是真的,map
因为Dictionary
s是元组的集合,而不仅仅是价值.所以可能有类似的东西mapValues
是正确的,但map
在集合上仍然不是真的.
map
真的是有用的,但要小心你实际上在做什么,因为你不能真正做map
的Set
到Set
.
归档时间: |
|
查看次数: |
5270 次 |
最近记录: |