Skip to content

Instantly share code, notes, and snippets.

@emorydunn
Last active April 3, 2019 01:11
Show Gist options
  • Save emorydunn/5c64059faa3f9ba90c41273dcff0e661 to your computer and use it in GitHub Desktop.
Save emorydunn/5c64059faa3f9ba90c41273dcff0e661 to your computer and use it in GitHub Desktop.
Add a counter to a URL
//
// IncrementCounter.swift
//
// Created by Emory Dunn on 2019-04-01.
//
import Foundation
extension URL {
/// Appends or increments a counter on a file name
///
/// The last integer in a file name is used as a counter, such that `Some File 1`
/// would be incremented to `Some File 2`. If there is no counter, `Some File`, a
/// counter will be added starting with `1`: `Some File 1`.
///
/// If a counter is found but can't be converted to an integer the file
/// will be treated as if it had no counter.
///
/// - Parameters:
/// - count: The initial counter to use if none exists
/// - increment: How much to increment the counter by
/// - format: A format string for the counter. Defaults to `"%01d"`
/// - delimiter: The string separating the file name and the counter. Defaults to `" "` (a single space)
/// - Returns: A new URL with a counter
mutating func incrementCounter(starting count: Int = 1, by increment: Int = 1, format: String = "%01d", delimiter: String = " ") {
self = self.incrementingCounter(starting: count, by: increment, format: format, delimiter: delimiter)
}
/// Returns a URL constructed by appending or incrementing a counter on a file name
///
/// The last integer in a file name is used as a counter, such that `Some File 1`
/// would be incremented to `Some File 2`. If there is no counter, `Some File`, a
/// counter will be added starting with `1`: `Some File 1`.
///
/// If a counter is found but can't be converted to an integer the file
/// will be treated as if it had no counter.
///
/// - Parameters:
/// - count: The initial counter to use if none exists
/// - increment: How much to increment the counter by
/// - format: A format string for the counter. Defaults to `"%01d"`
/// - delimiter: The string separating the file name and the counter. Defaults to `" "` (a single space)
/// - Returns: A new URL with a counter
func incrementingCounter(starting count: Int = 1, by increment: Int = 1, format: String = "%01d", delimiter: String = " ") -> URL {
// Break apart the URL
let ext = self.pathExtension
var fileName = self.deletingPathExtension().lastPathComponent
let tempDest = self.deletingLastPathComponent()
var counter = count
// Find any suffix digits
fileCounter: if let digitRange = fileName.range(of: "\(delimiter)\\d+$", options: .regularExpression) {
let delimiterSet = CharacterSet(charactersIn: delimiter)
// Extract the digits
let subString = String(fileName[digitRange]).trimmingCharacters(in: delimiterSet)
guard let fileCounter = Int(subString) else { break fileCounter}
// Increment the counter
counter = fileCounter + increment
// Remove the existing counter
fileName.removeSubrange(digitRange)
}
// Append the counter with a space
let formattedCounter = String(format: format, counter)
let newName = fileName.appending("\(delimiter)\(formattedCounter)")
return tempDest.appendingPathComponent(newName).appendingPathExtension(ext)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment