Extend array types using where clause in Swift

后端 未结 7 1959
青春惊慌失措
青春惊慌失措 2020-11-28 07:35

I\'d like to use the Accelerate framework to extend [Float] and [Double] but each of these requires a different implementation.

I tried the obvious:

         


        
相关标签:
7条回答
  • 2020-11-28 07:50

    So I didn't read the question properly. FloatingPointType is an existing protocol that is implemented by Double, Float and CGFloat, so

    Yes. I did it only yesterday to add a function to SequenceType where the elements had to be Equatable. This is a modification to restrict the elements to Float

    You need to use a where clause. This is my function below.

    public extension SequenceType where Self.Generator.Element: FloatingPointType
    {
        public func splitAt(separator: Generator.Element) -> [[Generator.Element]]
        {
            var ret: [[Generator.Element]] = []
            var thisPart: [Generator.Element] = []
    
            for element in self
            {
                if element == separator
                {
                    ret.append(thisPart)
                    thisPart = []
                }
                else
                {
                    thisPart.append(element)
                }
            }
            ret.append(thisPart)
            return ret
        }
    }
    
    [Float(1), Float(2), Float(3), Float(4)].splitAt(Float(2))
    // returns [[1],[3, 4]]
    [Double(1), Double(2), Double(3), Double(4)].splitAt(Double(3))
    // returns [[1, 2],[4]]
    

    NB I couldn't make this work for an array but SequenceType is more general anyway.

    0 讨论(0)
  • 2020-11-28 07:51

    Swift 3 on Xcode 8.2

    Just need to extend Sequence protocol and provide a where statement.

    let someString = "1, 2, 3, 4, 5, 6, 7, 8"
    
    extension String {        
      func toArrayOfElements() -> [String] {
        return self.components(separatedBy: ", ")
      }        
    }
    
    extension Sequence where Iterator.Element == String {        
      func toInt() -> [Int] {            
        return self.map {
          Int($0)!
        }
      }        
    }
    
    let arrayOfStrings = someString.toArrayOfElements()    
    print(arrayOfStrings)
    
    let arrayOfInts = arrayOfStrings.toInt()    
    print(arrayOfInts)
    
    0 讨论(0)
  • 2020-11-28 07:52

    This worked for me. I'm using Swift 5.

    extension Array where Iterator.Element == Float { }

    0 讨论(0)
  • 2020-11-28 07:53

    How about

    extension CollectionType where Generator.Element == Double {
    
    }
    

    Or If you want a little bit more:

    protocol ArithmeticType {
        func +(lhs: Self, rhs: Self) -> Self
        func -(lhs: Self, rhs: Self) -> Self
        func *(lhs: Self, rhs: Self) -> Self
        func /(lhs: Self, rhs: Self) -> Self
    }
    
    extension Double : ArithmeticType {}
    extension Float : ArithmeticType {}
    
    extension SequenceType where Generator.Element : protocol<FloatLiteralConvertible, ArithmeticType> {
        var sum : Generator.Element {
            return reduce(0.0, combine: +)
        }
    
        var product : Generator.Element {
            return reduce(1.0, combine: *)
        }
    }
    
    
    stride(from: 1.0, through: 10.0, by: 1.0).sum   // 55
    [1.5, 2.0, 3.5, 4.0, 5.5].product               // 231
    

    Works with Double and Float or any other type that you conform to the protocols ArithmeticType and FloatLiteralConvertible. If you need to access specific indices of your array, change SequenceType to CollectionType as you cannot do this with a sequence.

    0 讨论(0)
  • 2020-11-28 07:56

    If you only want to extend a specific Array you have to use a protocol for each type:

    protocol DoubleValue {
        var value: Double { get }
    }
    extension Double: DoubleValue {
        var value: Double { return self }
    }
    extension Array where Element: DoubleValue {
        // use the value property
    }
    
    // the same for Float
    protocol FloatValue {
        var value: Float { get }
    }
    
    extension Float: FloatValue {
        var value: Float { return self }
    }
    extension Array where Element: FloatValue {
        // use the value property
    }
    
    0 讨论(0)
  • 2020-11-28 08:05

    Swift 3 to the rescue!!

    extension Collection where Iterator.Element == Int {
        // `Collection` can be `Sequence`, etc
    }
    
    0 讨论(0)
提交回复
热议问题