Swift map(_:) extension for Set() ?

前端 未结 4 1386
情深已故
情深已故 2020-12-10 04:14
  let numberSet = Set(1...11)
  let divideSet = numberSet.map({  $0 / 10 }) 
  //Error: Set does not have a member named map   :(

Swift 1.2 support

4条回答
  •  夕颜
    夕颜 (楼主)
    2020-12-10 04:29

    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.

    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(transform: (Element) -> U) -> Set {
            return Set(self.lazy.map(transform))
        }
    }
    

    Example:

    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(transform: (T) -> U) -> Set {
            return Set(Swift.map(self, transform))
        }
    }
    

    Example:

    let numberSet = Set(1...11)
    
    let divideSet = numberSet.map { $0 / 2 }
    println(divideSet) // [5, 0, 2, 4, 1, 3]
    

    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]
    

    Another possible implementation is

    extension Set {
        func map(transform: (T) -> U) -> Set {
            return Set(lazy(self).map(transform))
        }
    }
    

    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.

提交回复
热议问题