How do I load a text file line by line into an array with swift?
With Swift 5, according to your needs, you can choose one of the 3 following ways in order to solve your problem.
StringProtocol's components(separatedBy:) methodFoundation provides String a method called components(separatedBy:) with the following declaration:
func components(separatedBy separator: CharacterSet) -> [String]
Returns an array containing substrings from the string that have been divided by characters in the given set.
The code sample below shows how to use components(separatedBy:) with its parameter set to CharacterSet.newlines in order to load the content of a text file line by line into an array:
import Foundation
let path = Bundle.main.path(forResource: "Lorem Ipsum", ofType: "txt")!
let text = try! String(contentsOfFile: path, encoding: String.Encoding.utf8)
let lines = text.components(separatedBy: CharacterSet.newlines)
print(lines)
As an alternative, you can use the overloading of components(separatedBy:) that takes a parameter of type String. The code sample below shows how to use it:
import Foundation
let path = Bundle.main.path(forResource: "Lorem Ipsum", ofType: "txt")!
let text = try! String(contentsOfFile: path, encoding: String.Encoding.utf8)
let lines = text.components(separatedBy: "\n")
print(lines)
⚠️ You should however prefer the overloading of components(separatedBy:) that takes a CharacterSet parameter and use it with the value CharacterSet.newlines as this will manage all new line characters (U+000A ~ U+000D, U+0085, U+2028, and U+2029).
StringProtocol's enumerateSubstrings(in:options:_:) methodFoundation provides String a method called enumerateSubstrings(in:options:_:). The code sample below shows how to use enumerateSubstrings(in:options:_:) with options parameter value set to String.EnumerationOptions.byLines in order to load the content of a text file line by line into an array:
import Foundation
let path = Bundle.main.path(forResource: "Lorem Ipsum", ofType: "txt")!
let text = try! String(contentsOfFile: path, encoding: String.Encoding.utf8)
let range = text.startIndex ..< text.endIndex
var lines = [String]()
text.enumerateSubstrings(in: range, options: String.EnumerationOptions.byLines) {
(substring, range, enclosingRange, stop) in
guard let substring = substring else { return }
lines.append(substring)
}
print(lines)
NLTokenizer's enumerateTokens(in:using:) methodNLTokenizer has a method called enumerateTokens(in:using:). enumerateTokens(in:using:) has the following declaration:
@nonobjc func enumerateTokens(in range: Range, using block: (Range, NLTokenizer.Attributes) -> Bool)
Enumerates over a given range of the string and calls the specified block for each token.
The code sample below shows how to use enumerateTokens(in:using:) in order to load the content of a text file line by line into an array:
import Foundation
import NaturalLanguage
let path = Bundle.main.path(forResource: "Lorem Ipsum", ofType: "txt")!
let text = try! String(contentsOfFile: path, encoding: String.Encoding.utf8)
let tokenizer = NLTokenizer(unit: .paragraph)
tokenizer.setLanguage(.english)
tokenizer.string = text
var lines = [String]()
tokenizer.enumerateTokens(in: text.startIndex ..< text.endIndex) { (range, attributes) -> Bool in
let line = String(text[range])
lines.append(line)
return true
}
print(lines)