Implement function to trim the whitespaces
This commit is contained in:
parent
1ca77e6ae7
commit
19e3ee98fa
|
@ -30,6 +30,8 @@ public struct CSV: IteratorProtocol, Sequence {
|
||||||
public var headerRow: [String]? { return _headerRow }
|
public var headerRow: [String]? { return _headerRow }
|
||||||
private var _headerRow: [String]? = nil
|
private var _headerRow: [String]? = nil
|
||||||
|
|
||||||
|
private let whitespaces: CharacterSet
|
||||||
|
|
||||||
internal init<T: IteratorProtocol>(
|
internal init<T: IteratorProtocol>(
|
||||||
iterator: T,
|
iterator: T,
|
||||||
hasHeaderRow: Bool,
|
hasHeaderRow: Bool,
|
||||||
|
@ -41,6 +43,10 @@ public struct CSV: IteratorProtocol, Sequence {
|
||||||
self.trimFields = trimFields
|
self.trimFields = trimFields
|
||||||
self.delimiter = delimiter
|
self.delimiter = delimiter
|
||||||
|
|
||||||
|
var whitespaces = CharacterSet.whitespaces
|
||||||
|
whitespaces.remove(delimiter)
|
||||||
|
self.whitespaces = whitespaces
|
||||||
|
|
||||||
if hasHeaderRow {
|
if hasHeaderRow {
|
||||||
guard let headerRow = next() else {
|
guard let headerRow = next() else {
|
||||||
throw CSVError.cannotReadHeaderRow
|
throw CSVError.cannotReadHeaderRow
|
||||||
|
@ -167,6 +173,13 @@ public struct CSV: IteratorProtocol, Sequence {
|
||||||
var field: String
|
var field: String
|
||||||
var end: Bool
|
var end: Bool
|
||||||
while true {
|
while true {
|
||||||
|
if trimFields {
|
||||||
|
// Trim the leading spaces
|
||||||
|
while next != nil && whitespaces.contains(next!) {
|
||||||
|
next = moveNext()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if next == nil {
|
if next == nil {
|
||||||
(field, end) = ("", true)
|
(field, end) = ("", true)
|
||||||
}
|
}
|
||||||
|
@ -195,7 +208,15 @@ public struct CSV: IteratorProtocol, Sequence {
|
||||||
while let c = next {
|
while let c = next {
|
||||||
if quoted {
|
if quoted {
|
||||||
if c == DQUOTE {
|
if c == DQUOTE {
|
||||||
let cNext = moveNext()
|
var cNext = moveNext()
|
||||||
|
|
||||||
|
if trimFields {
|
||||||
|
// Trim the trailing spaces
|
||||||
|
while cNext != nil && whitespaces.contains(cNext!) {
|
||||||
|
cNext = moveNext()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if cNext == nil || cNext == CR || cNext == LF {
|
if cNext == nil || cNext == CR || cNext == LF {
|
||||||
if cNext == CR {
|
if cNext == CR {
|
||||||
let cNextNext = moveNext()
|
let cNextNext = moveNext()
|
||||||
|
@ -215,7 +236,7 @@ public struct CSV: IteratorProtocol, Sequence {
|
||||||
field.append(String(DQUOTE))
|
field.append(String(DQUOTE))
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// ERROR??
|
// ERROR?
|
||||||
field.append(String(c))
|
field.append(String(c))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -231,10 +252,21 @@ public struct CSV: IteratorProtocol, Sequence {
|
||||||
back = cNext
|
back = cNext
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if trimFields {
|
||||||
|
// Trim the trailing spaces
|
||||||
|
field = field.trimmingCharacters(in: whitespaces)
|
||||||
|
}
|
||||||
|
|
||||||
// END ROW
|
// END ROW
|
||||||
return (field, true)
|
return (field, true)
|
||||||
}
|
}
|
||||||
else if c == delimiter {
|
else if c == delimiter {
|
||||||
|
if trimFields {
|
||||||
|
// Trim the trailing spaces
|
||||||
|
field = field.trimmingCharacters(in: whitespaces)
|
||||||
|
}
|
||||||
|
|
||||||
// END FIELD
|
// END FIELD
|
||||||
return (field, false)
|
return (field, false)
|
||||||
}
|
}
|
||||||
|
@ -246,6 +278,12 @@ public struct CSV: IteratorProtocol, Sequence {
|
||||||
next = moveNext()
|
next = moveNext()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if trimFields {
|
||||||
|
// Trim the trailing spaces
|
||||||
|
field = field.trimmingCharacters(in: whitespaces)
|
||||||
|
}
|
||||||
|
|
||||||
|
// END FILE
|
||||||
return (field, true)
|
return (field, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -255,4 +255,24 @@ class CSVTests: XCTestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testTrimFields11() {
|
||||||
|
let csvString = " abc \n def "
|
||||||
|
var csv = try! CSV(string: csvString, trimFields: true)
|
||||||
|
|
||||||
|
let row1 = csv.next()!
|
||||||
|
XCTAssertEqual(row1, ["abc"])
|
||||||
|
let row2 = csv.next()!
|
||||||
|
XCTAssertEqual(row2, ["def"])
|
||||||
|
}
|
||||||
|
|
||||||
|
func testTrimFields12() {
|
||||||
|
let csvString = " \"abc\" \n \"def\" "
|
||||||
|
var csv = try! CSV(string: csvString, trimFields: true)
|
||||||
|
|
||||||
|
let row1 = csv.next()!
|
||||||
|
XCTAssertEqual(row1, ["abc"])
|
||||||
|
let row2 = csv.next()!
|
||||||
|
XCTAssertEqual(row2, ["def"])
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue