Skip to content

Instantly share code, notes, and snippets.

@jakehawken
Created April 4, 2022 04:09
Show Gist options
  • Save jakehawken/b340de341908c8407a98982e9a5ebdbb to your computer and use it in GitHub Desktop.
Save jakehawken/b340de341908c8407a98982e9a5ebdbb to your computer and use it in GitHub Desktop.
extension Array {
func scan(forEachNeighbors action: (Element, Element) -> Void) {
guard count >= 2 else {
return
}
var indexA = 0
var indexB = 1
while indexB <= count - 1 {
let elementA = self[indexA]
let elementB = self[indexB]
action(elementA, elementB)
indexA += 1
indexB += 1
}
}
}
@michaelrockhold
Copy link

michaelrockhold commented Apr 6, 2022

Or what if

import Foundation

extension Array {
    func adjacent_pairs() -> AnySequence<ArraySlice<Element>> {
        var idx = self.startIndex
        return AnySequence {
            return AnyIterator {
                if idx >= self.endIndex { return nil }
                let nextEnd = self.index(idx, offsetBy: 2)
                if nextEnd > self.endIndex { return nil }

                defer { idx = self.index(after: idx) }
                return self[idx ..< nextEnd]
            }
        }
    }
}

for i in [1,2,3,4,5,6,7].adjacent_pairs() {
    print(i)
}

@jakehawken
Copy link
Author

@michaelrockhold Hmm... That doesn't print the (6, 7) pair.

@michaelrockhold
Copy link

It wouldn't be an original Rock code if it didn't have an off-by-one bug (but I fixed it)

@michaelrockhold
Copy link

And of course this is more in the spirit of your scan() function:

[1,2,3,4,5,6,7].adjacent_pairs().forEach { i in
    print(i)
}

@jakehawken
Copy link
Author

I gotta ask: Snake case in Swift? Surely you need more boundaries in your life.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment