Skip to content

Instantly share code, notes, and snippets.

@rnapier
Last active May 31, 2018 11:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save rnapier/6dbc3b1bb728d104f397d98a8556db23 to your computer and use it in GitHub Desktop.
Save rnapier/6dbc3b1bb728d104f397d98a8556db23 to your computer and use it in GitHub Desktop.
let xs = [0,1,2,3,4,5]
let double: (Int) -> Int = { $0 * 2 }
let isEven: (Int) -> Bool = { $0 % 2 == 0 }
// Goal: [0,2,4,6,4,10]. Double all but the last even element.
// This impl makes me sad. Lots of state and copies the entire collection twice (once during transforming, and once to unreverse)
extension Collection {
func mapExceptLast(matching predicate: (Element) -> Bool, transform: (Element) -> Element) -> [Element] {
var result: [Element] = []
var found = false
for element in reversed() {
if !found && predicate(element) {
result.append(element)
found = true
} else {
result.append(transform(element))
}
}
return Array(result.reversed())
}
}
print(xs.mapExceptLast(matching: isEven, transform: double))
@rajivjhoomuck
Copy link

extension Collection {
  func mapExceptLast(matching predicate: (Element) -> Bool, transform: (Element) -> Element) -> [Element] {
    var found = false
    return Array(
      reversed().reduce(into: [Element]()) { (inoutResult, next) in
        guard !found && predicate(next) else {
          if predicate(next) { found = true }
          return inoutResult.append(transform(next))
        }
        return inoutResult.append(next)
    }).reversed()
  }
}

My attempt -> still copies twice though

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