Reputation: 309
I have an array of strings that contains a time pattern (e.g '30 min'):
let arrayOfStrings: [String] = ["Episode 1 - 23 min", "Episode 2 - 42 min", "Episode 3 - 45 min"]
func convertToTimeInterval(from string: String) -> TimeInterval {
// logic here...
return timeInterval // Double
}
So using such a method, I want from the results:
arrayOfStrings.forEach { string in
print(convertToTimeInterval(from: string))
}
// Prints
1380 // timeinterval from "23 min"
2520 // timeinterval from "42 min"
2700 // timeinterval from "45 min"
CharacterSet.separatedBy
but the string can contains multiple decimal that have nothing to do with the time (e.g Episode 1)Thanks for your help!
Upvotes: 0
Views: 885
Reputation: 285039
A rather underestimated but powerful API in Objective-C and Swift is (NS)Scanner.
Assuming there is always a hyphen and a whitespace character before the duration value just scanUpTo
"- " then scan the pattern and then scan the numeric value as Double and multiply it with 60.
func convertToTimeInterval(from string: String) -> TimeInterval? {
let scanner = Scanner(string: string)
scanner.scanUpToString("- ")
scanner.scanString("- ")
guard let duration = scanner.scanDouble() else { return nil }
return duration * 60.0
}
Or – a bit more elaborate – with NSRegularExpression. The pattern captures one or more digits after " - "
func convertToTimeInterval(from string: String) -> TimeInterval? {
let regex = try! NSRegularExpression(pattern: #"\s-\s(\d+)"#)
guard let firstMatch = regex.firstMatch(in: string, range: NSRange(string.startIndex..., in: string)) else { return nil }
let durationRange = Range(firstMatch.range(at: 1), in: string)!
return Double((string[durationRange]))! * 60.0
}
However it becomes more convenient with the new Regex API introduced in Swift 5.7
func convertToTimeInterval(from string: String) -> TimeInterval? {
let regex = Regex {
" - "
Capture { OneOrMore(.digit) } transform: {
Double($0)! * 60.0
}
}
return string.firstMatch(of: regex)?.output.1
}
Upvotes: 2
Reputation: 36119
you could try this approach, where each string in the array is split into sections, and the minutes extracted and returned as a Double/TimeInterval.
This should (not tested) cater for multiple languages that uses Western Arabic numerals
let arrayOfStrings: [String] = ["Episode 1 - 23 min", "Episode 2 - 42 min", "Episode 3 - 45 min"]
arrayOfStrings.forEach { string in
let t = convertToTimeInterval(from: string)
print("--> timeInterval: \(t) minutes or \(t * 60) seconds")
}
func convertToTimeInterval(from string: String) -> TimeInterval {
if let last = string.split(separator: "-").last {
let term2 = last.split(separator: " ")
if let minutes = term2.first {
if let result = Double(minutes.trimmingCharacters(in: .whitespacesAndNewlines)) {
return result
}
}
}
return 0.0 // <-- adjust as desired
}
Upvotes: 0