提问者:小点点

Swift map(_:)扩展Set()?


  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上不起作用,所以我决定在我的操场上变得聪明并尝试:

 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(_:)有什么想法吗?。谢谢大家。


共3个答案

匿名用户

更新:Swift 2和3发生了很大变化。Set的通用占位符现在是Element而不是T,并且所有集合都有一个返回数组的map()方法。

关于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。浮点除法不会发生这种情况:

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))
    }
}

这里懒(self)返回一个LazyForwardCollection,它有一个map()方法,并且再次返回一个LazyForwardCollection。优点可能是不创建中间数组。

匿名用户

Set.map(_:)的问题与Dictionary.map(_:)相同,他们没有在Swift模块(标准库)中实现它,因为实际上没有正确的方法来实现它。原因是:mapping不仅仅是枚举(您可以对for-in中的任何SequenceType进行枚举),而是将(通过参数闭包)每个值转换为另一个值。因此,您会期望结果中包含所有转换(元素),但你猜怎么着,如果值相同,它们就会折叠(对于Dicrix只有键是这样的)。

例如(使用提议的实现)Set([1,2,3,4,5]). map{1}.count==1

这也是为什么Swift.map返回一个Array,而不是作为source参数传递的相同类型的SequenceType/Collection Type

稍微离题一点,Dicrix(如前所述)在键值上有相同的问题(基本上是Set),因此任何适用于Set的map

匿名用户

从Swift 2.0开始,Collection Type协议(由Set实现)有一个map方法。