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(_:)
似乎不适用于集合,所以我决定在我的操场上变聪明并尝试:
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(_ :)的任何想法? 谢谢你们。
答案 0 :(得分:13)
更新:使用Swift 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))
}
}
示例:
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.浮点除法不会发生这种情况:
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
。
优点可能是没有创建中间数组。
答案 1 :(得分:7)
Set.map(_:)
的问题与Dictionary.map(_:)
的问题相同,他们没有在Swift
模块(标准库)中实现它,因为实际上< em>没有正确的方法来实现它。原因是:map
ping不仅仅是枚举(您可以对SequenceType
中的任何for-in
执行此操作),但它会进行转换(使用参数闭包) )每个值到另一个。所以你会期望结果中包含所有transform(element)
,但是猜猜看,如果值相同则会崩溃(对于Dictionary
s,只有键的行为是这样的。)
e.g。 (提议的实施)
Set([1, 2, 3, 4, 5]).map { 1 }.count == 1
这也是为什么Swift.map
返回Array
而不是同一类型的SequenceType
/ CollectionType
作为source
参数传递的原因。< / p>
稍微偏离,Dictionary
(如前所述)在键值上存在相同的问题(基本上是Set
),因此任何map
都可以在{ {1}}或Set<K>
没有确保一致的映射,但只更改值的那个就没问题了。它不会是真正的Set<(K, V)>
,因为map
是元组的集合,而不仅仅是值。因此可能会有类似于Dictionary
的内容,这些内容是正确的,但在集合上仍然不是真正的mapValues
。
map
非常有用,但要注意你实际做的事情,因为你不能真的< / em>从map
到map
执行Set
。
答案 2 :(得分:1)
从Swift 2.0开始,CollectionType
协议(由Set
实现)具有map
方法。
答案 3 :(得分:0)
我为groupId
作了扩展:
Set
例如:
extension Set {
/// Map, but for a `Set`.
/// - Parameter transform: The transform to apply to each element.
func map<T>(_ transform: (Element) throws -> T) rethrows -> Set<T> {
var tempSet = Set<T>()
try forEach {
tempSet.insert(try transform($0))
}
return tempSet
}
}