Created
January 27, 2018 15:19
-
-
Save ahknight/d350d4f04a0fb6e3200fd02db8438455 to your computer and use it in GitHub Desktop.
Iterates over a large string line-by-line, with configurable line endings. Uses Swift 4's Substring for efficiency.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// LineParser.swift | |
// | |
// Created by Adam Knight on 1/26/18. | |
// | |
import Foundation | |
public class LineParser: Sequence, IteratorProtocol { | |
public let text: String | |
private var remaining: Substring | |
var currentIndex: String.Index | |
var delimiter: String | |
public init(_ text: String, delimiter: String = "\r\n") { | |
self.text = text | |
self.delimiter = delimiter | |
remaining = text[text.startIndex..<text.endIndex] | |
currentIndex = remaining.startIndex | |
} | |
public func next() -> Substring? { | |
let line: Substring | |
// Find the next delimiter | |
if let range = remaining.range(of: delimiter, options: .literal) { | |
// Get the line | |
line = remaining[remaining.startIndex..<range.lowerBound] | |
// Update the remaining text | |
remaining = remaining[range.upperBound..<remaining.endIndex] | |
// Update the current index. | |
currentIndex = range.upperBound | |
return line | |
} | |
// Are we done? Use nil as EOF. | |
if remaining.isEmpty { return nil } | |
// Return the rest of the string as the last line. | |
line = remaining | |
remaining = remaining[remaining.endIndex..<remaining.endIndex] | |
return line | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment