From d55ddf0fb70dbbc480a8290b621484dc7fc16433 Mon Sep 17 00:00:00 2001 From: Kare Morstol Date: Thu, 10 Dec 2015 02:35:41 +0100 Subject: [PATCH] Implement handling of allowEmptySlices, add LazyCollectionType.split . Proper unit tests, also of standard library CollectionType.split, to ensure they do the same. --- SwiftShell/General/Collection.swift | 26 +++++-- .../General/Collection_Tests.swift | 71 +++++++++++++++---- 2 files changed, 78 insertions(+), 19 deletions(-) diff --git a/SwiftShell/General/Collection.swift b/SwiftShell/General/Collection.swift index 106c550..e20c183 100644 --- a/SwiftShell/General/Collection.swift +++ b/SwiftShell/General/Collection.swift @@ -5,29 +5,43 @@ * */ -public struct LazySplitGenerator : GeneratorType { +public struct LazySplitSequence : GeneratorType, LazySequenceType { private var remaining: Base.SubSequence? private let separator: Base.Generator.Element + private let allowEmptySlices: Bool - public init (base: Base, separator: Base.Generator.Element) { + public init (base: Base, separator: Base.Generator.Element, allowEmptySlices: Bool = false) { self.separator = separator self.remaining = base[base.startIndex.. Base.SubSequence? { guard let remaining = self.remaining else { return nil } - let (head,tail) = remaining.splitOnce(separator) + let (head,tail) = remaining.splitOnce(separator, allowEmptySlices: allowEmptySlices) self.remaining = tail return head } + + public func generate() -> LazySplitSequence { return self } } -extension CollectionType where Generator.Element: Equatable { +extension CollectionType where Generator.Element: Equatable, SubSequence: CollectionType, SubSequence.Generator.Element==Generator.Element, SubSequence==SubSequence.SubSequence { public func splitOnce (separator: Generator.Element, allowEmptySlices: Bool = false) -> (head: SubSequence, tail: SubSequence?) { guard let nextindex = indexOf(separator) else { return (self[startIndex.. LazySplitSequence { + return LazySplitSequence(base: self.elements, separator: separator, allowEmptySlices: allowEmptySlices) } } diff --git a/SwiftShellTests/General/Collection_Tests.swift b/SwiftShellTests/General/Collection_Tests.swift index ce7cb13..4a36043 100644 --- a/SwiftShellTests/General/Collection_Tests.swift +++ b/SwiftShellTests/General/Collection_Tests.swift @@ -11,24 +11,69 @@ import XCTest class LazySplitGenerator_Tests: XCTestCase { - func splitToArray (s: String) -> [String] { - let g = LazySplitGenerator(base: s.characters, separator: " " as Character) - return AnySequence {g} .map {String($0)} + func lazySplitToArray (allowEmptySlices allowEmptySlices: Bool) (_ s: String) -> [String] { + let seq: LazySplitSequence = s.characters.lazy.split("," as Character, allowEmptySlices: allowEmptySlices) + return seq.map {String($0)} } - func testStrings () { - XCTAssertEqual(splitToArray("abc def"), ["abc","def"]) - XCTAssertEqual(splitToArray(" a"), ["","a"]) - XCTAssertEqual(splitToArray("a "), ["a",""]) - XCTAssertEqual(splitToArray("a b"), ["a","","b"]) + func testStringsLazySplit_AllowingEmptySlices () { + let split = lazySplitToArray(allowEmptySlices: true) + + XCTAssertEqual(split("ab,c,de,f"), ["ab","c","de","f"]) + XCTAssertEqual(split(",a"), ["","a"]) + XCTAssertEqual(split("a,"), ["a",""]) + XCTAssertEqual(split("a,,b,,,c"), ["a","","b","","","c"]) + XCTAssertEqual(split(""), [""]) + XCTAssertEqual(split(","), ["",""]) + XCTAssertEqual(split("ab"), ["ab"]) } - func splitIntsToArray (s: [Int]) -> [[Int]] { - let g = LazySplitGenerator(base: s, separator: 0) - return AnySequence {g} .map {Array($0)} + func testCollectionTypeSplit_AllowingEmptySlices () { + let split = {(s: String) -> [String] in + s.characters.split(",", allowEmptySlices: true).map {String($0)} + } + + XCTAssertEqual(split("ab,c,de,f"), ["ab","c","de","f"]) + XCTAssertEqual(split(",a"), ["","a"]) + XCTAssertEqual(split("a,"), ["a",""]) + XCTAssertEqual(split("a,,b,,,c"), ["a","","b","","","c"]) + XCTAssertEqual(split(""), [""]) + XCTAssertEqual(split(","), ["",""]) + XCTAssertEqual(split("ab"), ["ab"]) } - func testInts () { - XCTAssertEqual(splitIntsToArray([1,2,0,4,0,6,7,8,9]), [[1,2],[4],[6,7,8,9]]) + func testStringsLazySplit_NoEmptySlices () { + let split = lazySplitToArray(allowEmptySlices: false) + + XCTAssertEqual(split("ab,c,de,f"), ["ab","c","de","f"]) + XCTAssertEqual(split(",a"), ["a"]) + XCTAssertEqual(split("a,"), ["a"]) + XCTAssertEqual(split("a,,b,,,c"), ["a","b","c"]) + XCTAssertEqual(split(""), []) + XCTAssertEqual(split(","), []) + XCTAssertEqual(split("ab"), ["ab"]) + } + + func testCollectionTypeSplit_NoEmptySlices () { + let split = {(s: String) -> [String] in + s.characters.split(",", allowEmptySlices: false).map {String($0)} + } + + XCTAssertEqual(split("ab,c,de,f"), ["ab","c","de","f"]) + XCTAssertEqual(split(",a"), ["a"]) + XCTAssertEqual(split("a,"), ["a"]) + XCTAssertEqual(split("a,,b,,,c"), ["a","b","c"]) + XCTAssertEqual(split(""), []) + XCTAssertEqual(split(","), []) + XCTAssertEqual(split("ab"), ["ab"]) + } + + func testIntsLazySplit_NoEmptySlices () { + let split = {(s: [Int]) -> [[Int]] in + s.lazy.split(0, allowEmptySlices: false).map {Array($0)} + } + + XCTAssertEqual(split([1,2,0,4,0,6,7,8,9]), [[1,2],[4],[6,7,8,9]]) } } +