Set() 的 Swift map(_:) 扩展? [英] Swift map(_:) extension for Set() ?

查看:26
本文介绍了Set() 的 Swift map(_:) 扩展?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  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,所以我决定在我的游乐场并尝试过:

Swift 1.2 supports Set() for unordered collections, but map(_:) doesn't seem to work on Sets, so i decide to get smart on my playground and tried:

 let stringSet = Set(map(numberSet, { String($0)}))
 println(stringSet)
 stringSet =  ["2", "11", "1", "8", "6", "4", "3", "9", "7", "10", "5]

这似乎奏效了.所以我尝试扩展 Set:

This seemed to work. So I tried extending 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"

我认为它不起作用是有充分理由的,就像这里的例子:

And i think there is a good reason why it doesn’t work, like this example here:

   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(_:) 的任何想法?.谢谢各位.

Any ideas on how to extend Set to use map(_:) reliably ?. Thank guys.

推荐答案

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

Update: Quite a lot changed with Swift 2 and 3. The generic placeholder of Set is now Element instead of T, and all collections have a map() method which returns an array.

对于 Set -> 的问题也有很好的争论.设置映射(如不同元素映射到相同结果).另一方面,这种映射可能有一个用例,所以这里是 Swift 3 的更新(现在使用不同的名称).

There were also good arguments given about the problems of a Set -> Set mapping (such as different elements mapping to the same result). On the other hand, there may be a use-case for such a mapping, so here is an update for Swift 3 (now using a different name).

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]

<小时>

(旧答案:) 你快到了.出于某种原因,泛型类型必须明确指定返回的集合:


(Old answer:) You were almost there. For some reason, the generic type of the returned set must be specified explicitly:

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

The resulting set has less elements because the integer division $0 / 2 truncates the quotient, e.g. both 4/2 and 5/2 map to the same element 2. This does not happen with floating point division:

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.优点可能是没有创建中间数组.

Here lazy(self) returns a LazyForwardCollection which has a map() method and that returns a LazyForwardCollection again. The advantage might be that no intermediate array is created.

这篇关于Set() 的 Swift map(_:) 扩展?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆