44

I'm getting this error and am new to Swift. I want to take the last 5 points of an array >= 5, and pass those 5 points as an array argument to a function. How can I achieve this and get past this error?

Cannot convert value of type 'ArraySlice' to expected argument type '[CGPoint]'

if (self.points?.count >= 5) {
    let lastFivePoints = self.points![(self.points!.count-5)..<self.points!.count]
    let angle = VectorCalculator.angleWithArrayOfPoints(lastFivePoints)
}
chris P
  • 6,359
  • 11
  • 40
  • 84

3 Answers3

51

You need to convert ArraySlice to Array using method Array(Slice<Type>)

if (self.points?.count >= 5) {
    let lastFivePoints = Array(self.points![(self.points!.count-5)..<self.points!.count])
    let angle = VectorCalculator.angleWithArrayOfPoints(lastFivePoints)
}
deoKasuhal
  • 2,867
  • 20
  • 27
  • 2
    Doesn't this negate the advantages of ArraySlice by instantiating a new Array; causing another allocation of memory. – scord Mar 02 '20 at 04:02
4

Instead of the range operator you can use prefix(upTo end: Self.Index) method that return ArraySlice which makes your code shorter. Method's definition: The method returns a subsequence from the start of the collection up to, but not including, the specified position (index).

if (self.points?.count >= 5) {
  let lastFivePoints = Array<CGPoint>(self.points?.prefix(upTo:5)) as [AnyObject]
  let angle = VectorCalculator.angleWithArrayOfPoints(lastFivePoints)
}

// You can also do this 

let lastFivePoints = Array<CGPoint>(self.points?[0...4]) 
Ohmy
  • 2,201
  • 21
  • 24
2

I tried using Array(lastFivePoints) but i got error

Type of expression is ambiguous without more context

enter image description here

I ended up doing:

let arr = lastFivePoints.map({ (x) -> T in
                            return x
                        })

where T is the content class CGPoint for this example

Ted
  • 22,696
  • 11
  • 95
  • 109