From 2f0628f1b31bd4d01662c65164439ce3af8c0db9 Mon Sep 17 00:00:00 2001 From: Colin Eberhardt Date: Tue, 24 Jun 2014 19:16:28 +0100 Subject: [PATCH 1/6] Added initial sequence operations --- ExSwift.xcodeproj/project.pbxproj | 84 +++++-------------------- ExSwift/Sequence.swift | 48 ++++++++++++++ ExSwiftTests/ExSwiftSequenceTests.swift | 50 +++++++++++++++ 3 files changed, 114 insertions(+), 68 deletions(-) create mode 100644 ExSwift/Sequence.swift create mode 100644 ExSwiftTests/ExSwiftSequenceTests.swift diff --git a/ExSwift.xcodeproj/project.pbxproj b/ExSwift.xcodeproj/project.pbxproj index 68647d0..040033d 100644 --- a/ExSwift.xcodeproj/project.pbxproj +++ b/ExSwift.xcodeproj/project.pbxproj @@ -7,30 +7,6 @@ objects = { /* Begin PBXBuildFile section */ - 1E11AF8A1943222D006BCE48 /* ExSwift.h in Headers */ = {isa = PBXBuildFile; fileRef = 1E11AF891943222D006BCE48 /* ExSwift.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 1E11AFA619432236006BCE48 /* ExSwiftArrayTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFA019432236006BCE48 /* ExSwiftArrayTests.swift */; }; - 1E11AFA719432236006BCE48 /* ExSwiftDictionaryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFA119432236006BCE48 /* ExSwiftDictionaryTests.swift */; }; - 1E11AFA819432236006BCE48 /* ExSwiftFloatTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFA219432236006BCE48 /* ExSwiftFloatTests.swift */; }; - 1E11AFA919432236006BCE48 /* ExSwiftIntTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFA319432236006BCE48 /* ExSwiftIntTests.swift */; }; - 1E11AFAA19432236006BCE48 /* ExSwiftRangeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFA419432236006BCE48 /* ExSwiftRangeTests.swift */; }; - 1E11AFAB19432236006BCE48 /* ExSwiftStringTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFA519432236006BCE48 /* ExSwiftStringTests.swift */; }; - 1E11AFB21943225B006BCE48 /* Array.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFAC1943225B006BCE48 /* Array.swift */; }; - 1E11AFB41943225B006BCE48 /* Dictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFAD1943225B006BCE48 /* Dictionary.swift */; }; - 1E11AFB61943225B006BCE48 /* Float.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFAE1943225B006BCE48 /* Float.swift */; }; - 1E11AFB81943225B006BCE48 /* Int.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFAF1943225B006BCE48 /* Int.swift */; }; - 1E11AFBA1943225B006BCE48 /* Range.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFB01943225B006BCE48 /* Range.swift */; }; - 1E11AFBC1943225B006BCE48 /* String.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFB11943225B006BCE48 /* String.swift */; }; - 1EA5F68A194387CA00E8A40F /* ExSwiftTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EA5F689194387CA00E8A40F /* ExSwiftTests.swift */; }; - 1EC241FC1946E91B0047109A /* NSArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EC241FB1946E91B0047109A /* NSArray.swift */; }; - 1EC241FE1946E92E0047109A /* ExSwiftNSArrayTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EC241FD1946E92E0047109A /* ExSwiftNSArrayTests.swift */; }; - 1ED536841943863100BDA94E /* ExSwift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1ED536831943863100BDA94E /* ExSwift.swift */; }; - 1ED8FC30194EF9E1004F829A /* ExSwiftDictionaryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFA119432236006BCE48 /* ExSwiftDictionaryTests.swift */; }; - 1ED8FC31194EF9E1004F829A /* ExSwiftFloatTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFA219432236006BCE48 /* ExSwiftFloatTests.swift */; }; - 1ED8FC32194EF9E1004F829A /* ExSwiftIntTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFA319432236006BCE48 /* ExSwiftIntTests.swift */; }; - 1ED8FC33194EF9E1004F829A /* ExSwiftRangeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFA419432236006BCE48 /* ExSwiftRangeTests.swift */; }; - 1ED8FC34194EF9E1004F829A /* ExSwiftStringTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFA519432236006BCE48 /* ExSwiftStringTests.swift */; }; - 1ED8FC35194EF9E1004F829A /* ExSwiftTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EA5F689194387CA00E8A40F /* ExSwiftTests.swift */; }; - 1ED8FC36194EF9E1004F829A /* ExSwiftNSArrayTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EC241FD1946E92E0047109A /* ExSwiftNSArrayTests.swift */; }; 2EB34F05195473AC00A8D2AF /* ExSwift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1ED536831943863100BDA94E /* ExSwift.swift */; }; 2EB34F06195473AC00A8D2AF /* Array.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFAC1943225B006BCE48 /* Array.swift */; }; 2EB34F07195473AC00A8D2AF /* Dictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFAD1943225B006BCE48 /* Dictionary.swift */; }; @@ -47,16 +23,12 @@ 2EB34F121954744D00A8D2AF /* Range.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFB01943225B006BCE48 /* Range.swift */; }; 2EB34F131954744D00A8D2AF /* String.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFB11943225B006BCE48 /* String.swift */; }; 2EB34F141954744D00A8D2AF /* NSArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EC241FB1946E91B0047109A /* NSArray.swift */; }; - 2EC02FC9194ED0F000619CB5 /* ExSwiftArrayTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFA019432236006BCE48 /* ExSwiftArrayTests.swift */; }; - 2EC02FCA194ED10500619CB5 /* ExSwift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1ED536831943863100BDA94E /* ExSwift.swift */; }; - 2EC02FCB194ED10500619CB5 /* Array.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFAC1943225B006BCE48 /* Array.swift */; }; - 2EC02FCC194ED10500619CB5 /* Dictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFAD1943225B006BCE48 /* Dictionary.swift */; }; - 2EC02FCD194ED10500619CB5 /* Float.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFAE1943225B006BCE48 /* Float.swift */; }; - 2EC02FCE194ED10500619CB5 /* Int.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFAF1943225B006BCE48 /* Int.swift */; }; - 2EC02FCF194ED10500619CB5 /* Range.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFB01943225B006BCE48 /* Range.swift */; }; - 2EC02FD0194ED10500619CB5 /* String.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFB11943225B006BCE48 /* String.swift */; }; - 2EC02FD1194ED10500619CB5 /* NSArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EC241FB1946E91B0047109A /* NSArray.swift */; }; - 2EC02FD2194ED10500619CB5 /* ExSwift.h in Headers */ = {isa = PBXBuildFile; fileRef = 1E11AF891943222D006BCE48 /* ExSwift.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 3CC8BE601959A9AC00AD3292 /* Sequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CC8BE5F1959A9AC00AD3292 /* Sequence.swift */; }; + 3CC8BE611959A9B200AD3292 /* Sequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CC8BE5F1959A9AC00AD3292 /* Sequence.swift */; }; + 3CC8BE621959A9B200AD3292 /* Sequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CC8BE5F1959A9AC00AD3292 /* Sequence.swift */; }; + 3CC8BE631959A9B300AD3292 /* Sequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CC8BE5F1959A9AC00AD3292 /* Sequence.swift */; }; + 3CC8BE651959A9F700AD3292 /* ExSwiftSequenceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CC8BE641959A9F700AD3292 /* ExSwiftSequenceTests.swift */; }; + 3CC8BE661959A9F700AD3292 /* ExSwiftSequenceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CC8BE641959A9F700AD3292 /* ExSwiftSequenceTests.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -83,6 +55,8 @@ 1ED536831943863100BDA94E /* ExSwift.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExSwift.swift; sourceTree = ""; }; 2E8CE8EB194ECF2A008B9919 /* ExSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ExSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 2EC02FBD194ED0D500619CB5 /* ExSwift-iOS Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "ExSwift-iOS Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + 3CC8BE5F1959A9AC00AD3292 /* Sequence.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Sequence.swift; sourceTree = ""; }; + 3CC8BE641959A9F700AD3292 /* ExSwiftSequenceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExSwiftSequenceTests.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -140,6 +114,7 @@ 1E11AF861943222D006BCE48 /* ExSwift */ = { isa = PBXGroup; children = ( + 3CC8BE5F1959A9AC00AD3292 /* Sequence.swift */, 1ED536831943863100BDA94E /* ExSwift.swift */, 1E11AFAC1943225B006BCE48 /* Array.swift */, 1E11AFAD1943225B006BCE48 /* Dictionary.swift */, @@ -165,6 +140,7 @@ 1E11AF931943222D006BCE48 /* ExSwiftTests */ = { isa = PBXGroup; children = ( + 3CC8BE641959A9F700AD3292 /* ExSwiftSequenceTests.swift */, 1E11AFA019432236006BCE48 /* ExSwiftArrayTests.swift */, 1E11AFA119432236006BCE48 /* ExSwiftDictionaryTests.swift */, 1E11AFA219432236006BCE48 /* ExSwiftFloatTests.swift */, @@ -193,7 +169,6 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 1E11AF8A1943222D006BCE48 /* ExSwift.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -201,7 +176,6 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 2EC02FD2194ED10500619CB5 /* ExSwift.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -359,14 +333,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 1EC241FC1946E91B0047109A /* NSArray.swift in Sources */, - 1E11AFBC1943225B006BCE48 /* String.swift in Sources */, - 1E11AFB21943225B006BCE48 /* Array.swift in Sources */, - 1ED536841943863100BDA94E /* ExSwift.swift in Sources */, - 1E11AFB41943225B006BCE48 /* Dictionary.swift in Sources */, - 1E11AFB61943225B006BCE48 /* Float.swift in Sources */, - 1E11AFB81943225B006BCE48 /* Int.swift in Sources */, - 1E11AFBA1943225B006BCE48 /* Range.swift in Sources */, + 3CC8BE601959A9AC00AD3292 /* Sequence.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -374,21 +341,15 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 1E11AFAA19432236006BCE48 /* ExSwiftRangeTests.swift in Sources */, 2EB34F09195473AC00A8D2AF /* Int.swift in Sources */, 2EB34F06195473AC00A8D2AF /* Array.swift in Sources */, - 1E11AFA619432236006BCE48 /* ExSwiftArrayTests.swift in Sources */, - 1EC241FE1946E92E0047109A /* ExSwiftNSArrayTests.swift in Sources */, 2EB34F07195473AC00A8D2AF /* Dictionary.swift in Sources */, - 1E11AFA819432236006BCE48 /* ExSwiftFloatTests.swift in Sources */, - 1E11AFA719432236006BCE48 /* ExSwiftDictionaryTests.swift in Sources */, + 3CC8BE611959A9B200AD3292 /* Sequence.swift in Sources */, + 3CC8BE651959A9F700AD3292 /* ExSwiftSequenceTests.swift in Sources */, 2EB34F0C195473AC00A8D2AF /* NSArray.swift in Sources */, 2EB34F05195473AC00A8D2AF /* ExSwift.swift in Sources */, 2EB34F08195473AC00A8D2AF /* Float.swift in Sources */, - 1E11AFAB19432236006BCE48 /* ExSwiftStringTests.swift in Sources */, - 1E11AFA919432236006BCE48 /* ExSwiftIntTests.swift in Sources */, 2EB34F0B195473AC00A8D2AF /* String.swift in Sources */, - 1EA5F68A194387CA00E8A40F /* ExSwiftTests.swift in Sources */, 2EB34F0A195473AC00A8D2AF /* Range.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -397,14 +358,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 2EC02FD1194ED10500619CB5 /* NSArray.swift in Sources */, - 2EC02FCD194ED10500619CB5 /* Float.swift in Sources */, - 2EC02FCA194ED10500619CB5 /* ExSwift.swift in Sources */, - 2EC02FCE194ED10500619CB5 /* Int.swift in Sources */, - 2EC02FCF194ED10500619CB5 /* Range.swift in Sources */, - 2EC02FD0194ED10500619CB5 /* String.swift in Sources */, - 2EC02FCB194ED10500619CB5 /* Array.swift in Sources */, - 2EC02FCC194ED10500619CB5 /* Dictionary.swift in Sources */, + 3CC8BE621959A9B200AD3292 /* Sequence.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -412,21 +366,15 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 1ED8FC30194EF9E1004F829A /* ExSwiftDictionaryTests.swift in Sources */, 2EB34F111954744D00A8D2AF /* Int.swift in Sources */, 2EB34F0E1954744D00A8D2AF /* Array.swift in Sources */, - 1ED8FC31194EF9E1004F829A /* ExSwiftFloatTests.swift in Sources */, - 1ED8FC32194EF9E1004F829A /* ExSwiftIntTests.swift in Sources */, 2EB34F0F1954744D00A8D2AF /* Dictionary.swift in Sources */, - 1ED8FC33194EF9E1004F829A /* ExSwiftRangeTests.swift in Sources */, - 1ED8FC34194EF9E1004F829A /* ExSwiftStringTests.swift in Sources */, + 3CC8BE631959A9B300AD3292 /* Sequence.swift in Sources */, + 3CC8BE661959A9F700AD3292 /* ExSwiftSequenceTests.swift in Sources */, 2EB34F141954744D00A8D2AF /* NSArray.swift in Sources */, 2EB34F0D1954744D00A8D2AF /* ExSwift.swift in Sources */, 2EB34F101954744D00A8D2AF /* Float.swift in Sources */, - 1ED8FC35194EF9E1004F829A /* ExSwiftTests.swift in Sources */, - 1ED8FC36194EF9E1004F829A /* ExSwiftNSArrayTests.swift in Sources */, 2EB34F131954744D00A8D2AF /* String.swift in Sources */, - 2EC02FC9194ED0F000619CB5 /* ExSwiftArrayTests.swift in Sources */, 2EB34F121954744D00A8D2AF /* Range.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/ExSwift/Sequence.swift b/ExSwift/Sequence.swift new file mode 100644 index 0000000..62690c6 --- /dev/null +++ b/ExSwift/Sequence.swift @@ -0,0 +1,48 @@ +// +// Sequence.swift +// ExSwift +// +// Created by Colin Eberhardt on 24/06/2014. +// Copyright (c) 2014 pNre. All rights reserved. +// + +import Foundation + +extension SequenceOf { + + func first () -> T? { + var generator = self.generate(); + return generator.next() + } + + func skip (n:Int) -> SequenceOf { + var generator = self.generate(); + for _ in 0..n { + generator.next() + } + return SequenceOf(generator) + } + + func skipWhile(condition:(T) -> Bool) -> SequenceOf { + var generator = self.generate(); + var keepSkipping = true + while keepSkipping { + if let nextItem = generator.next() { + keepSkipping = condition(nextItem) + } else { + keepSkipping = false + } + } + return SequenceOf(generator) + } + + func contains (item: T) -> Bool { + var generator = self.generate(); + while let nextItem = generator.next() { + if nextItem as T == item { + return true; + } + } + return false + } +} diff --git a/ExSwiftTests/ExSwiftSequenceTests.swift b/ExSwiftTests/ExSwiftSequenceTests.swift new file mode 100644 index 0000000..0d5d0b2 --- /dev/null +++ b/ExSwiftTests/ExSwiftSequenceTests.swift @@ -0,0 +1,50 @@ +// +// ExSwiftSequenceTests.swift +// ExSwift +// +// Created by Colin Eberhardt on 24/06/2014. +// Copyright (c) 2014 pNre. All rights reserved. +// + +import XCTest + +class ExtensionsSequenceTests: XCTestCase { + + var sequence = 1...5 + var emptySequence = 1..1 + + func testFirst () { + var first = SequenceOf(sequence).first() + XCTAssertEqual(first!, 1) + } + + func testFirstEmotySequence () { + var first = SequenceOf(emptySequence).first() + XCTAssertNil(first) + } + + func testSkip () { + var skipped = SequenceOf(sequence).skip(2) + XCTAssertEqualObjects(Array(skipped), [3,4,5]) + } + + func testSkipBeyondEnd () { + var skipped = SequenceOf(sequence).skip(8) + XCTAssertEqualObjects(Array(skipped), []) + } + + func testSkipWhile () { + var skipped = SequenceOf(sequence).skipWhile { $0 < 3 } + XCTAssertEqualObjects(Array(skipped), [4,5]) + } + + func testSkipWhileBeyondEnd () { + var skipped = SequenceOf(sequence).skipWhile { $0 < 20 } + XCTAssertEqualObjects(Array(skipped), []) + } + + func testContains () { + XCTAssertTrue(SequenceOf(sequence).contains(1)) + XCTAssertFalse(SequenceOf(sequence).contains(56)) + } +} \ No newline at end of file From 310d0cd20d089a07e0d2b6a8cafc090dd20422a4 Mon Sep 17 00:00:00 2001 From: Colin Eberhardt Date: Thu, 26 Jun 2014 08:33:02 +0100 Subject: [PATCH 2/6] Added a 'take' operation --- ExSwift/Sequence.swift | 29 +++++++++++++++++++++++++ ExSwiftTests/ExSwiftSequenceTests.swift | 10 +++++++++ 2 files changed, 39 insertions(+) diff --git a/ExSwift/Sequence.swift b/ExSwift/Sequence.swift index 62690c6..37adb8f 100644 --- a/ExSwift/Sequence.swift +++ b/ExSwift/Sequence.swift @@ -8,6 +8,7 @@ import Foundation + extension SequenceOf { func first () -> T? { @@ -45,4 +46,32 @@ extension SequenceOf { } return false } + + func take (n:Int) -> SequenceOf { + return SequenceOf(TakeSequence(self, n)) + } } + +// a sequence adapter that implements the 'take' functionality +struct TakeSequence: Sequence { + let sequence:S + let n: Int + + init(_ sequence:S, _ n:Int) { + self.sequence = sequence + self.n = n + } + + func generate() -> GeneratorOf { + var count = 0 + var generator = self.sequence.generate() + return GeneratorOf { + count++ + if count > self.n { + return nil + } else { + return generator.next() + } + } + } +} \ No newline at end of file diff --git a/ExSwiftTests/ExSwiftSequenceTests.swift b/ExSwiftTests/ExSwiftSequenceTests.swift index 0d5d0b2..0130e73 100644 --- a/ExSwiftTests/ExSwiftSequenceTests.swift +++ b/ExSwiftTests/ExSwiftSequenceTests.swift @@ -47,4 +47,14 @@ class ExtensionsSequenceTests: XCTestCase { XCTAssertTrue(SequenceOf(sequence).contains(1)) XCTAssertFalse(SequenceOf(sequence).contains(56)) } + + func testTake () { + var take = SequenceOf(sequence).take(2) + XCTAssertEqualObjects(Array(take), [1,2]) + } + + func testTakeBeyondSequenceEnd () { + var take = SequenceOf(sequence).take(20) + XCTAssertEqualObjects(Array(take), [1,2,3,4,5]) + } } \ No newline at end of file From d3ed38dd88e41511aba5180383080f489223c5f8 Mon Sep 17 00:00:00 2001 From: Colin Eberhardt Date: Thu, 26 Jun 2014 08:43:41 +0100 Subject: [PATCH 3/6] Added a take-while implementation --- ExSwift/Sequence.swift | 35 +++++++++++++++++++++++-- ExSwiftTests/ExSwiftSequenceTests.swift | 16 +++++++++++ 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/ExSwift/Sequence.swift b/ExSwift/Sequence.swift index 37adb8f..a7a720d 100644 --- a/ExSwift/Sequence.swift +++ b/ExSwift/Sequence.swift @@ -50,14 +50,18 @@ extension SequenceOf { func take (n:Int) -> SequenceOf { return SequenceOf(TakeSequence(self, n)) } + + func takeWhile (condition:(T?) -> Bool) -> SequenceOf { + return SequenceOf(TakeWhileSequence(self, condition)) + } } // a sequence adapter that implements the 'take' functionality struct TakeSequence: Sequence { - let sequence:S + let sequence: S let n: Int - init(_ sequence:S, _ n:Int) { + init(_ sequence: S, _ n: Int) { self.sequence = sequence self.n = n } @@ -74,4 +78,31 @@ struct TakeSequence: Sequence { } } } +} + +// a sequence adapter that implements the 'take' functionality +struct TakeWhileSequence: Sequence { + let sequence: S + let condition: (S.GeneratorType.Element?) -> Bool + + init(_ sequence:S, _ condition:(S.GeneratorType.Element?) -> Bool) { + self.sequence = sequence + self.condition = condition + } + + func generate() -> GeneratorOf { + var generator = self.sequence.generate() + var endConditionMet = false + return GeneratorOf { + let next: S.GeneratorType.Element? = generator.next() + if !endConditionMet { + endConditionMet = !self.condition(next) + } + if endConditionMet { + return nil + } else { + return next + } + } + } } \ No newline at end of file diff --git a/ExSwiftTests/ExSwiftSequenceTests.swift b/ExSwiftTests/ExSwiftSequenceTests.swift index 0130e73..89d98f9 100644 --- a/ExSwiftTests/ExSwiftSequenceTests.swift +++ b/ExSwiftTests/ExSwiftSequenceTests.swift @@ -57,4 +57,20 @@ class ExtensionsSequenceTests: XCTestCase { var take = SequenceOf(sequence).take(20) XCTAssertEqualObjects(Array(take), [1,2,3,4,5]) } + + func testTakeWhile () { + var take = SequenceOf(sequence).takeWhile { $0 != 3 } + XCTAssertEqualObjects(Array(take), [1,2]) + } + + func testTakeWhileConditionNeverTrue () { + var take = SequenceOf(sequence).takeWhile { $0 == 7 } + XCTAssertEqualObjects(Array(take), []) + } + + func testTakeWhileConditionNotMet () { + var take = SequenceOf(sequence).takeWhile { $0 != 7 } + XCTAssertEqualObjects(Array(take), [1,2,3,4,5]) + } + } \ No newline at end of file From 7a820353f0a69cd82bb6f00f4ade5128dfabdabd Mon Sep 17 00:00:00 2001 From: Colin Eberhardt Date: Thu, 26 Jun 2014 17:09:27 +0100 Subject: [PATCH 4/6] Implemented many more operations --- ExSwift/Sequence.swift | 98 ++++++++++++++++++++++++- ExSwiftTests/ExSwiftSequenceTests.swift | 52 +++++++++++++ 2 files changed, 149 insertions(+), 1 deletion(-) diff --git a/ExSwift/Sequence.swift b/ExSwift/Sequence.swift index a7a720d..6e3cd2c 100644 --- a/ExSwift/Sequence.swift +++ b/ExSwift/Sequence.swift @@ -16,6 +16,42 @@ extension SequenceOf { return generator.next() } + func any (call: (T) -> Bool) -> Bool { + var generator = self.generate(); + while let nextItem = generator.next() { + if call(nextItem) { + return true + } + } + return false + } + + func get (index: Int) -> T? { + var generator = self.generate(); + for _ in 0..(index-1) { + generator.next() + } + return generator.next() + } + + func get (range: Range) -> SequenceOf { + return self.skip(range.startIndex) + .take(range.endIndex - range.startIndex) + } + + func indexOf (item: U) -> Int? { + var index = 0; + for current in self { + if let equatable = current as? U { + if equatable == item { + return index + } + } + index++ + } + return nil + } + func skip (n:Int) -> SequenceOf { var generator = self.generate(); for _ in 0..n { @@ -24,6 +60,16 @@ extension SequenceOf { return SequenceOf(generator) } + func filter(includeElement: (T) -> Bool) -> SequenceOf { + return SequenceOf(FilterSequence(self, includeElement)) + } + + func reject (exclude: (T -> Bool)) -> SequenceOf { + return self.filter { + return !exclude($0) + } + } + func skipWhile(condition:(T) -> Bool) -> SequenceOf { var generator = self.generate(); var keepSkipping = true @@ -54,6 +100,56 @@ extension SequenceOf { func takeWhile (condition:(T?) -> Bool) -> SequenceOf { return SequenceOf(TakeWhileSequence(self, condition)) } + + //TODO: methods that make sense to add to sequence + + // unique () + // flatten () -> OutType[] + + // DONE + + // reject (exclude: (Element -> Bool)) -> SequenceOf + // any (call: (Element) -> Bool) -> Bool + // get (range: Range) -> SequenceOf + // get (index: Int) -> Element? + // indexOf (item: U) -> Int? + // first () -> T? + // takeWhile (condition:(Element?) -> Bool) -> SequenceOf + // take (n:Int) -> SequenceOf + // contains (item: T) -> Bool + // skip (n:Int) -> SequenceOf + // skipWhile(condition:(T) -> Bool) -> SequenceOf +} + +// a sequence adapter that implements the 'filter' functionality +struct FilterSequence: Sequence { + let sequence: S + let includeElement: (S.GeneratorType.Element) -> Bool + + init(_ sequence: S, _ includeElement: (S.GeneratorType.Element) -> Bool) { + self.sequence = sequence + self.includeElement = includeElement + } + + func generate() -> GeneratorOf { + var generator = self.sequence.generate() + return GeneratorOf { + var keepSkipping = true + var nextItem = generator.next() + while keepSkipping { + if let unwrappedItem = nextItem { + keepSkipping = !self.includeElement(unwrappedItem) + } else { + keepSkipping = false + } + + if (keepSkipping) { + nextItem = generator.next() + } + } + return nextItem + } + } } // a sequence adapter that implements the 'take' functionality @@ -80,7 +176,7 @@ struct TakeSequence: Sequence { } } -// a sequence adapter that implements the 'take' functionality +// a sequence adapter that implements the 'takeWhile' functionality struct TakeWhileSequence: Sequence { let sequence: S let condition: (S.GeneratorType.Element?) -> Bool diff --git a/ExSwiftTests/ExSwiftSequenceTests.swift b/ExSwiftTests/ExSwiftSequenceTests.swift index 89d98f9..fc30be9 100644 --- a/ExSwiftTests/ExSwiftSequenceTests.swift +++ b/ExSwiftTests/ExSwiftSequenceTests.swift @@ -73,4 +73,56 @@ class ExtensionsSequenceTests: XCTestCase { XCTAssertEqualObjects(Array(take), [1,2,3,4,5]) } + func testIndexOf () { + XCTAssertEqual(SequenceOf(sequence).indexOf(2)!, 1) + XCTAssertNil(SequenceOf(sequence).indexOf(77)) + } + + func testGet () { + XCTAssertEqual(SequenceOf(sequence).get(3)!, 3) + XCTAssertNil(SequenceOf(sequence).get(22)) + } + + func testGetRange () { + var subSequence = SequenceOf(sequence).get(1..3) + XCTAssertEqualObjects(Array(subSequence), [2,3]) + + subSequence = SequenceOf(sequence).get(0..0) + XCTAssertEqualObjects(Array(subSequence), []) + } + + func testGetRangeOutOfBounds () { + var subSequence = SequenceOf(sequence).get(10..15) + XCTAssertEqualObjects(Array(subSequence), []) + } + + func testAny () { + XCTAssertTrue(SequenceOf(sequence).any { $0 == 1 }) + XCTAssertFalse(SequenceOf(sequence).any { $0 == 77 }) + } + + func testFilter () { + var evens = SequenceOf(sequence).filter { $0 % 2 == 0 } + XCTAssertEqualObjects(Array(evens), [2,4]) + + var odds = SequenceOf(sequence).filter { $0 % 2 == 1 } + XCTAssertEqualObjects(Array(odds), [1,3,5]) + + var all = SequenceOf(sequence).filter { $0 < 10 } + XCTAssertEqualObjects(Array(all), [1,2,3,4,5]) + + var none = SequenceOf(sequence).filter { $0 > 10 } + XCTAssertEqualObjects(Array(none), []) + } + + func testReject () { + var rejected = SequenceOf(sequence).reject { $0 == 3 } + XCTAssertEqualObjects(Array(rejected), [1,2,4,5]) + + rejected = SequenceOf(sequence).reject { $0 == 1 } + XCTAssertEqualObjects(Array(rejected), [2,3,4,5]) + + rejected = SequenceOf(sequence).reject { $0 == 10 } + XCTAssertEqualObjects(Array(rejected), [1,2,3,4,5]) + } } \ No newline at end of file From 571c1c8d3de70c957f29b84ea3bf5c814e34f807 Mon Sep 17 00:00:00 2001 From: Colin Eberhardt Date: Thu, 26 Jun 2014 17:30:56 +0100 Subject: [PATCH 5/6] Added some API documentation --- ExSwift.xcodeproj/project.pbxproj | 100 +++++++++++++++++++++++++----- ExSwift/Sequence.swift | 80 +++++++++++++++++------- 2 files changed, 143 insertions(+), 37 deletions(-) diff --git a/ExSwift.xcodeproj/project.pbxproj b/ExSwift.xcodeproj/project.pbxproj index 040033d..a7f6979 100644 --- a/ExSwift.xcodeproj/project.pbxproj +++ b/ExSwift.xcodeproj/project.pbxproj @@ -7,6 +7,30 @@ objects = { /* Begin PBXBuildFile section */ + 1E11AF8A1943222D006BCE48 /* ExSwift.h in Headers */ = {isa = PBXBuildFile; fileRef = 1E11AF891943222D006BCE48 /* ExSwift.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1E11AFA619432236006BCE48 /* ExSwiftArrayTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFA019432236006BCE48 /* ExSwiftArrayTests.swift */; }; + 1E11AFA719432236006BCE48 /* ExSwiftDictionaryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFA119432236006BCE48 /* ExSwiftDictionaryTests.swift */; }; + 1E11AFA819432236006BCE48 /* ExSwiftFloatTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFA219432236006BCE48 /* ExSwiftFloatTests.swift */; }; + 1E11AFA919432236006BCE48 /* ExSwiftIntTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFA319432236006BCE48 /* ExSwiftIntTests.swift */; }; + 1E11AFAA19432236006BCE48 /* ExSwiftRangeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFA419432236006BCE48 /* ExSwiftRangeTests.swift */; }; + 1E11AFAB19432236006BCE48 /* ExSwiftStringTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFA519432236006BCE48 /* ExSwiftStringTests.swift */; }; + 1E11AFB21943225B006BCE48 /* Array.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFAC1943225B006BCE48 /* Array.swift */; }; + 1E11AFB41943225B006BCE48 /* Dictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFAD1943225B006BCE48 /* Dictionary.swift */; }; + 1E11AFB61943225B006BCE48 /* Float.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFAE1943225B006BCE48 /* Float.swift */; }; + 1E11AFB81943225B006BCE48 /* Int.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFAF1943225B006BCE48 /* Int.swift */; }; + 1E11AFBA1943225B006BCE48 /* Range.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFB01943225B006BCE48 /* Range.swift */; }; + 1E11AFBC1943225B006BCE48 /* String.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFB11943225B006BCE48 /* String.swift */; }; + 1EA5F68A194387CA00E8A40F /* ExSwiftTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EA5F689194387CA00E8A40F /* ExSwiftTests.swift */; }; + 1EC241FC1946E91B0047109A /* NSArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EC241FB1946E91B0047109A /* NSArray.swift */; }; + 1EC241FE1946E92E0047109A /* ExSwiftNSArrayTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EC241FD1946E92E0047109A /* ExSwiftNSArrayTests.swift */; }; + 1ED536841943863100BDA94E /* ExSwift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1ED536831943863100BDA94E /* ExSwift.swift */; }; + 1ED8FC30194EF9E1004F829A /* ExSwiftDictionaryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFA119432236006BCE48 /* ExSwiftDictionaryTests.swift */; }; + 1ED8FC31194EF9E1004F829A /* ExSwiftFloatTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFA219432236006BCE48 /* ExSwiftFloatTests.swift */; }; + 1ED8FC32194EF9E1004F829A /* ExSwiftIntTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFA319432236006BCE48 /* ExSwiftIntTests.swift */; }; + 1ED8FC33194EF9E1004F829A /* ExSwiftRangeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFA419432236006BCE48 /* ExSwiftRangeTests.swift */; }; + 1ED8FC34194EF9E1004F829A /* ExSwiftStringTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFA519432236006BCE48 /* ExSwiftStringTests.swift */; }; + 1ED8FC35194EF9E1004F829A /* ExSwiftTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EA5F689194387CA00E8A40F /* ExSwiftTests.swift */; }; + 1ED8FC36194EF9E1004F829A /* ExSwiftNSArrayTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EC241FD1946E92E0047109A /* ExSwiftNSArrayTests.swift */; }; 2EB34F05195473AC00A8D2AF /* ExSwift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1ED536831943863100BDA94E /* ExSwift.swift */; }; 2EB34F06195473AC00A8D2AF /* Array.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFAC1943225B006BCE48 /* Array.swift */; }; 2EB34F07195473AC00A8D2AF /* Dictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFAD1943225B006BCE48 /* Dictionary.swift */; }; @@ -23,12 +47,22 @@ 2EB34F121954744D00A8D2AF /* Range.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFB01943225B006BCE48 /* Range.swift */; }; 2EB34F131954744D00A8D2AF /* String.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFB11943225B006BCE48 /* String.swift */; }; 2EB34F141954744D00A8D2AF /* NSArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EC241FB1946E91B0047109A /* NSArray.swift */; }; - 3CC8BE601959A9AC00AD3292 /* Sequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CC8BE5F1959A9AC00AD3292 /* Sequence.swift */; }; - 3CC8BE611959A9B200AD3292 /* Sequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CC8BE5F1959A9AC00AD3292 /* Sequence.swift */; }; - 3CC8BE621959A9B200AD3292 /* Sequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CC8BE5F1959A9AC00AD3292 /* Sequence.swift */; }; - 3CC8BE631959A9B300AD3292 /* Sequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CC8BE5F1959A9AC00AD3292 /* Sequence.swift */; }; - 3CC8BE651959A9F700AD3292 /* ExSwiftSequenceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CC8BE641959A9F700AD3292 /* ExSwiftSequenceTests.swift */; }; - 3CC8BE661959A9F700AD3292 /* ExSwiftSequenceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CC8BE641959A9F700AD3292 /* ExSwiftSequenceTests.swift */; }; + 2EC02FC9194ED0F000619CB5 /* ExSwiftArrayTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFA019432236006BCE48 /* ExSwiftArrayTests.swift */; }; + 2EC02FCA194ED10500619CB5 /* ExSwift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1ED536831943863100BDA94E /* ExSwift.swift */; }; + 2EC02FCB194ED10500619CB5 /* Array.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFAC1943225B006BCE48 /* Array.swift */; }; + 2EC02FCC194ED10500619CB5 /* Dictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFAD1943225B006BCE48 /* Dictionary.swift */; }; + 2EC02FCD194ED10500619CB5 /* Float.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFAE1943225B006BCE48 /* Float.swift */; }; + 2EC02FCE194ED10500619CB5 /* Int.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFAF1943225B006BCE48 /* Int.swift */; }; + 2EC02FCF194ED10500619CB5 /* Range.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFB01943225B006BCE48 /* Range.swift */; }; + 2EC02FD0194ED10500619CB5 /* String.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E11AFB11943225B006BCE48 /* String.swift */; }; + 2EC02FD1194ED10500619CB5 /* NSArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EC241FB1946E91B0047109A /* NSArray.swift */; }; + 2EC02FD2194ED10500619CB5 /* ExSwift.h in Headers */ = {isa = PBXBuildFile; fileRef = 1E11AF891943222D006BCE48 /* ExSwift.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 3C0AB978195C7FAF0009BDA0 /* Sequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C0AB977195C7FAF0009BDA0 /* Sequence.swift */; }; + 3C0AB979195C7FB20009BDA0 /* Sequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C0AB977195C7FAF0009BDA0 /* Sequence.swift */; }; + 3C0AB97A195C7FB30009BDA0 /* Sequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C0AB977195C7FAF0009BDA0 /* Sequence.swift */; }; + 3C0AB97B195C7FB30009BDA0 /* Sequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C0AB977195C7FAF0009BDA0 /* Sequence.swift */; }; + 3C0AB97D195C7FBC0009BDA0 /* ExSwiftSequenceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C0AB97C195C7FBC0009BDA0 /* ExSwiftSequenceTests.swift */; }; + 3C0AB97E195C7FC20009BDA0 /* ExSwiftSequenceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C0AB97C195C7FBC0009BDA0 /* ExSwiftSequenceTests.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -55,8 +89,8 @@ 1ED536831943863100BDA94E /* ExSwift.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExSwift.swift; sourceTree = ""; }; 2E8CE8EB194ECF2A008B9919 /* ExSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ExSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 2EC02FBD194ED0D500619CB5 /* ExSwift-iOS Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "ExSwift-iOS Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; - 3CC8BE5F1959A9AC00AD3292 /* Sequence.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Sequence.swift; sourceTree = ""; }; - 3CC8BE641959A9F700AD3292 /* ExSwiftSequenceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExSwiftSequenceTests.swift; sourceTree = ""; }; + 3C0AB977195C7FAF0009BDA0 /* Sequence.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Sequence.swift; sourceTree = ""; }; + 3C0AB97C195C7FBC0009BDA0 /* ExSwiftSequenceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExSwiftSequenceTests.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -114,7 +148,7 @@ 1E11AF861943222D006BCE48 /* ExSwift */ = { isa = PBXGroup; children = ( - 3CC8BE5F1959A9AC00AD3292 /* Sequence.swift */, + 3C0AB977195C7FAF0009BDA0 /* Sequence.swift */, 1ED536831943863100BDA94E /* ExSwift.swift */, 1E11AFAC1943225B006BCE48 /* Array.swift */, 1E11AFAD1943225B006BCE48 /* Dictionary.swift */, @@ -140,7 +174,7 @@ 1E11AF931943222D006BCE48 /* ExSwiftTests */ = { isa = PBXGroup; children = ( - 3CC8BE641959A9F700AD3292 /* ExSwiftSequenceTests.swift */, + 3C0AB97C195C7FBC0009BDA0 /* ExSwiftSequenceTests.swift */, 1E11AFA019432236006BCE48 /* ExSwiftArrayTests.swift */, 1E11AFA119432236006BCE48 /* ExSwiftDictionaryTests.swift */, 1E11AFA219432236006BCE48 /* ExSwiftFloatTests.swift */, @@ -169,6 +203,7 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 1E11AF8A1943222D006BCE48 /* ExSwift.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -176,6 +211,7 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 2EC02FD2194ED10500619CB5 /* ExSwift.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -333,7 +369,15 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 3CC8BE601959A9AC00AD3292 /* Sequence.swift in Sources */, + 1EC241FC1946E91B0047109A /* NSArray.swift in Sources */, + 1E11AFBC1943225B006BCE48 /* String.swift in Sources */, + 3C0AB978195C7FAF0009BDA0 /* Sequence.swift in Sources */, + 1E11AFB21943225B006BCE48 /* Array.swift in Sources */, + 1ED536841943863100BDA94E /* ExSwift.swift in Sources */, + 1E11AFB41943225B006BCE48 /* Dictionary.swift in Sources */, + 1E11AFB61943225B006BCE48 /* Float.swift in Sources */, + 1E11AFB81943225B006BCE48 /* Int.swift in Sources */, + 1E11AFBA1943225B006BCE48 /* Range.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -341,15 +385,23 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 1E11AFAA19432236006BCE48 /* ExSwiftRangeTests.swift in Sources */, 2EB34F09195473AC00A8D2AF /* Int.swift in Sources */, 2EB34F06195473AC00A8D2AF /* Array.swift in Sources */, + 1E11AFA619432236006BCE48 /* ExSwiftArrayTests.swift in Sources */, + 1EC241FE1946E92E0047109A /* ExSwiftNSArrayTests.swift in Sources */, 2EB34F07195473AC00A8D2AF /* Dictionary.swift in Sources */, - 3CC8BE611959A9B200AD3292 /* Sequence.swift in Sources */, - 3CC8BE651959A9F700AD3292 /* ExSwiftSequenceTests.swift in Sources */, + 3C0AB979195C7FB20009BDA0 /* Sequence.swift in Sources */, + 1E11AFA819432236006BCE48 /* ExSwiftFloatTests.swift in Sources */, + 1E11AFA719432236006BCE48 /* ExSwiftDictionaryTests.swift in Sources */, + 3C0AB97D195C7FBC0009BDA0 /* ExSwiftSequenceTests.swift in Sources */, 2EB34F0C195473AC00A8D2AF /* NSArray.swift in Sources */, 2EB34F05195473AC00A8D2AF /* ExSwift.swift in Sources */, 2EB34F08195473AC00A8D2AF /* Float.swift in Sources */, + 1E11AFAB19432236006BCE48 /* ExSwiftStringTests.swift in Sources */, + 1E11AFA919432236006BCE48 /* ExSwiftIntTests.swift in Sources */, 2EB34F0B195473AC00A8D2AF /* String.swift in Sources */, + 1EA5F68A194387CA00E8A40F /* ExSwiftTests.swift in Sources */, 2EB34F0A195473AC00A8D2AF /* Range.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -358,7 +410,15 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 3CC8BE621959A9B200AD3292 /* Sequence.swift in Sources */, + 2EC02FD1194ED10500619CB5 /* NSArray.swift in Sources */, + 2EC02FCD194ED10500619CB5 /* Float.swift in Sources */, + 3C0AB97A195C7FB30009BDA0 /* Sequence.swift in Sources */, + 2EC02FCA194ED10500619CB5 /* ExSwift.swift in Sources */, + 2EC02FCE194ED10500619CB5 /* Int.swift in Sources */, + 2EC02FCF194ED10500619CB5 /* Range.swift in Sources */, + 2EC02FD0194ED10500619CB5 /* String.swift in Sources */, + 2EC02FCB194ED10500619CB5 /* Array.swift in Sources */, + 2EC02FCC194ED10500619CB5 /* Dictionary.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -366,15 +426,23 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 1ED8FC30194EF9E1004F829A /* ExSwiftDictionaryTests.swift in Sources */, 2EB34F111954744D00A8D2AF /* Int.swift in Sources */, 2EB34F0E1954744D00A8D2AF /* Array.swift in Sources */, + 1ED8FC31194EF9E1004F829A /* ExSwiftFloatTests.swift in Sources */, + 1ED8FC32194EF9E1004F829A /* ExSwiftIntTests.swift in Sources */, 2EB34F0F1954744D00A8D2AF /* Dictionary.swift in Sources */, - 3CC8BE631959A9B300AD3292 /* Sequence.swift in Sources */, - 3CC8BE661959A9F700AD3292 /* ExSwiftSequenceTests.swift in Sources */, + 3C0AB97B195C7FB30009BDA0 /* Sequence.swift in Sources */, + 1ED8FC33194EF9E1004F829A /* ExSwiftRangeTests.swift in Sources */, + 1ED8FC34194EF9E1004F829A /* ExSwiftStringTests.swift in Sources */, + 3C0AB97E195C7FC20009BDA0 /* ExSwiftSequenceTests.swift in Sources */, 2EB34F141954744D00A8D2AF /* NSArray.swift in Sources */, 2EB34F0D1954744D00A8D2AF /* ExSwift.swift in Sources */, 2EB34F101954744D00A8D2AF /* Float.swift in Sources */, + 1ED8FC35194EF9E1004F829A /* ExSwiftTests.swift in Sources */, + 1ED8FC36194EF9E1004F829A /* ExSwiftNSArrayTests.swift in Sources */, 2EB34F131954744D00A8D2AF /* String.swift in Sources */, + 2EC02FC9194ED0F000619CB5 /* ExSwiftArrayTests.swift in Sources */, 2EB34F121954744D00A8D2AF /* Range.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/ExSwift/Sequence.swift b/ExSwift/Sequence.swift index 6e3cd2c..c3fd324 100644 --- a/ExSwift/Sequence.swift +++ b/ExSwift/Sequence.swift @@ -11,11 +11,20 @@ import Foundation extension SequenceOf { + /** + * First element of the sequence + * @return First element of the sequence if present + */ func first () -> T? { var generator = self.generate(); return generator.next() } + /** + * Checks if call returns true for any element of self + * @param call Function to call for each element + * @return True if call returns true for any element of self + */ func any (call: (T) -> Bool) -> Bool { var generator = self.generate(); while let nextItem = generator.next() { @@ -26,6 +35,11 @@ extension SequenceOf { return false } + /** + * Object at the specified index if exists + * @param index + * @return Object at index in sequence, nil if index is out of bounds + */ func get (index: Int) -> T? { var generator = self.generate(); for _ in 0..(index-1) { @@ -34,11 +48,21 @@ extension SequenceOf { return generator.next() } + /** + * Objects in the specified range + * @param range + * @return Subsequence in range + */ func get (range: Range) -> SequenceOf { return self.skip(range.startIndex) .take(range.endIndex - range.startIndex) } + /** + * Index of the first occurrence of item, if found + * @param item The item to search for + * @return Index of the matched item or nil + */ func indexOf (item: U) -> Int? { var index = 0; for current in self { @@ -52,6 +76,10 @@ extension SequenceOf { return nil } + /** + * Subsequence from n to the end of the sequence + * @return Sequence from n to the end + */ func skip (n:Int) -> SequenceOf { var generator = self.generate(); for _ in 0..n { @@ -60,16 +88,31 @@ extension SequenceOf { return SequenceOf(generator) } - func filter(includeElement: (T) -> Bool) -> SequenceOf { - return SequenceOf(FilterSequence(self, includeElement)) + /** + * Filters the sequence only including items that match the test + * @param include Function invoked to test elements for inclusion in the sequence + * @return Filtered sequence + */ + func filter(include: (T) -> Bool) -> SequenceOf { + return SequenceOf(FilterSequence(self, include)) } + /** + * Opposite of filter + * @param exclude Function invoked to test elements for exlcusion from the sequence + * @return Filtered sequence + */ func reject (exclude: (T -> Bool)) -> SequenceOf { return self.filter { return !exclude($0) } } + /** + * Skips the elements in the sequence up until the condition returns false + * @param condition A function which returns a boolean if an element satisfies a given condition or not + * @return Elements of the sequence starting with the element which does not meet the condition + */ func skipWhile(condition:(T) -> Bool) -> SequenceOf { var generator = self.generate(); var keepSkipping = true @@ -83,6 +126,11 @@ extension SequenceOf { return SequenceOf(generator) } + /** + * Checks if self contains the item object + * @param item The item to search for + * @return true if self contains item + */ func contains (item: T) -> Bool { var generator = self.generate(); while let nextItem = generator.next() { @@ -93,32 +141,22 @@ extension SequenceOf { return false } + /** + * Returns the first n elements from self + * @return First n elements + */ func take (n:Int) -> SequenceOf { return SequenceOf(TakeSequence(self, n)) } + /** + * Returns the elements of the sequence up until an element does not meet the condition + * @param condition A function which returns a boolean if an element satisfies a given condition or not. + * @return Elements of the sequence up until an element does not meet the condition + */ func takeWhile (condition:(T?) -> Bool) -> SequenceOf { return SequenceOf(TakeWhileSequence(self, condition)) } - - //TODO: methods that make sense to add to sequence - - // unique () - // flatten () -> OutType[] - - // DONE - - // reject (exclude: (Element -> Bool)) -> SequenceOf - // any (call: (Element) -> Bool) -> Bool - // get (range: Range) -> SequenceOf - // get (index: Int) -> Element? - // indexOf (item: U) -> Int? - // first () -> T? - // takeWhile (condition:(Element?) -> Bool) -> SequenceOf - // take (n:Int) -> SequenceOf - // contains (item: T) -> Bool - // skip (n:Int) -> SequenceOf - // skipWhile(condition:(T) -> Bool) -> SequenceOf } // a sequence adapter that implements the 'filter' functionality From e7cda62cc61f2f4a450729c2ba361c1e328011f6 Mon Sep 17 00:00:00 2001 From: Colin Eberhardt Date: Thu, 26 Jun 2014 17:49:07 +0100 Subject: [PATCH 6/6] Added project docs --- README.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/README.md b/README.md index babf7af..56b377d 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,8 @@ JavaScript (Lo-Dash, Underscore) & Ruby inspired set of Swift extensions for sta - [Operators](#operators-3) - [NSArray](#nsarray) - [Instance Methods](#instance-methods-6) + - [SequenceOf](#sequenceof) + - [Instance Methods](#instance-methods-7) - [Utilities](#utilities) - [Class Methods](#class-methods-5) @@ -256,6 +258,34 @@ Name | Signatures **`cast`**|`cast () -> OutType[]` **`flatten`**|`flatten () -> OutType[]` +## SequenceOf ## + +The following operations can be performed on sequences and are evaluated lazily. Each operation only takes the data it requires from the source sequence in order to return its result. + +The `Sequence` protocol cannot be extended, hence the following are extensions to `SequenceOf`. They can be used as follows: + +``` +var source: Sequence = ... +var filteredSequence = SequenceOf(source).filter { ... } +``` + +#### Instance Methods #### + +Name | Signatures +---- | ---------- +**`first`**|`first () -> T?` +**`any`**|`any (call: (T) -> Bool) -> Bool` +**`get`**|`get (index: Int) -> T?` +**`get`**|`get (range: Range) -> SequenceOf` +**`indexOf`**|`indexOf (item: U) -> Int?` +**`filter`**|`filter(include: (T) -> Bool) -> SequenceOf` +**`reject`**|`reject (exclude: (T -> Bool)) -> SequenceOf` +**`skipWhile`**|`skipWhile(condition:(T) -> Bool) -> SequenceOf` +**`skip`**|`skip (n:Int) -> SequenceOf` +**`contains`**|`contains (item: T) -> Bool` +**`take`**|`take (n:Int) -> SequenceOf` +**`takeWhile`**|`takeWhile (condition:(T?) -> Bool) -> SequenceOf` + # Utilities # Examples in the [Wiki](https://github.com/pNre/ExSwift/wiki/ExSwift)