jjatie
jjatie

Reputation: 5332

Use map to access next element in array

I want to transform an array of points into an array of lines like so:

let lines = points.map { $1 - $0 }

I get the error

Contextual closure type '(Point) -> _' expects 1 argument, but 2 were used in closure body

I understand why I am getting this, but I could have sworn I'd seen sample code on SO using multiple arguments in a map closure. Is there a similar function I'm not finding that can do this?

Upvotes: 1

Views: 1254

Answers (2)

user3441734
user3441734

Reputation: 17572

another possibility is using reduce. lets have

let arr = [1,2,3,4,5,6,7,8]
let n = 3 // number of points in the line
let l = arr.reduce([[]]) { (s, p) -> [[Int]] in
    var s = s
    if let l = s.last where l.count < n {
        var l = l
        l.append(p)
        s[s.endIndex - 1] = l
    } else {
        s.append([p])
    }
    return s
}
print(l) // [[1, 2, 3], [4, 5, 6], [7, 8]]

the advantage is that number of points in the line could be defined

Upvotes: 0

Luca Angeletti
Luca Angeletti

Reputation: 59536

My interpretation

Given an array of some CGPoint(s)

// pseudocode 
points = [a, b, c]

your want as output a list of segments

// pseudocode
segments = [(a, b), (b, c)]

Implementation

struct Segment {
    let from: CGPoint
    let to: CGPoint
}

let points = [CGPointZero, CGPoint(x: 1, y: 1), CGPoint(x: 2, y: 2)]

let segments = zip(points, points.dropFirst()).map(Segment.init)

@Martin R: Thank your for the suggestion!

Result

[Segment(from: (0.0, 0.0), to: (1.0, 1.0)), Segment(from: (1.0, 1.0), to: (2.0, 2.0))]

Upvotes: 6

Related Questions