From 39d89b9c3dd21ce89a4ecbb832db045c1f4f8213 Mon Sep 17 00:00:00 2001 From: pNre Date: Fri, 6 Jun 2014 20:50:57 +0200 Subject: [PATCH] reduceRight, implode, reduce, explode - Array (reduceRight, implode) - Dictionary (reduce) - String (explode) --- .../UserInterfaceState.xcuserstate | Bin 30200 -> 31726 bytes ExSwift/Array.swift | 44 ++++++++++++------ ExSwift/Dictionary.swift | 12 ++++- ExSwift/String.swift | 12 +++++ ExSwiftTests/ExSwiftArrayTests.swift | 26 ++++++++++- ExSwiftTests/ExSwiftDictionaryTests.swift | 12 +++++ ExSwiftTests/ExSwiftStringTests.swift | 7 +++ Examples/Array.md | 15 ++++++ Examples/Dictionary.md | 11 +++++ Examples/String.md | 10 +++- README.md | 6 ++- 11 files changed, 136 insertions(+), 19 deletions(-) diff --git a/ExSwift.xcodeproj/project.xcworkspace/xcuserdata/pie.xcuserdatad/UserInterfaceState.xcuserstate b/ExSwift.xcodeproj/project.xcworkspace/xcuserdata/pie.xcuserdatad/UserInterfaceState.xcuserstate index 75d482df6ad71dbb30be920b81a8d22dd80e4b39..93b6c3d610f55d45e3905255dc590d12dea9b11f 100644 GIT binary patch delta 17637 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 // Gets the longest array - let max = arrays.reduce(count, combine: { - (max: Int, item: Array) -> Int in - return item.count > max ? item.count : max; - }) + let max = arrays.map { (array: Array) -> Int in + return array.count + }.max() as Int for i in 0..max { - var item = Array() - - item.append(get(i)) - for array in arrays { - item.append(array.get(i)) - } - - result.append(item) + // i-th element in self as array + every i-th element in each array in arrays + result.append([get(i)] + arrays.map { + (array: Array) -> Any? in return array.get(i) + }) } @@ -327,9 +322,9 @@ extension Array { * Opposite of filter */ func reject (exclude: (T -> Bool)) -> Array { - return self.filter({ + return filter { return !exclude($0) - }) + } } /** @@ -388,6 +383,27 @@ extension Array { return result } + + /** + * Joins the array elements with a separator + * @param separator + * @return Joined object if self is not empty + * and its elements are instances of C, nil otherwise + */ + func implode (separator: C) -> C? { + if self.first() is C { + return Swift.join(separator, reinterpretCast(self) as Array) + } + + return nil + } + + /** + * self.reduce from right to left + */ + func reduceRight (initial: U, combine: (U, Element) -> U) -> U { + return self.reverse().reduce(initial, combine: combine) + } /** * Removes the last element from self and returns it diff --git a/ExSwift/Dictionary.swift b/ExSwift/Dictionary.swift index b0942d8..b01906a 100644 --- a/ExSwift/Dictionary.swift +++ b/ExSwift/Dictionary.swift @@ -7,6 +7,7 @@ // import Foundation +import Swift extension Dictionary { @@ -76,7 +77,7 @@ extension Dictionary { * @param testFunction * @return Filtered dictionary */ - func filter(testFunction test: (KeyType, ValueType) -> Bool) -> Dictionary { + func filter (testFunction test: (KeyType, ValueType) -> Bool) -> Dictionary { var result = Dictionary() @@ -185,7 +186,14 @@ extension Dictionary { return false } - + + /** + * Same as Array.reduce + */ + func reduce (initial: U, combine: (U, Element) -> U) -> U { + return Swift.reduce(self, initial, combine) + } + /** * Removes a (key, value) pair from self and returns it as tuple * @return (key, value) diff --git a/ExSwift/String.swift b/ExSwift/String.swift index ffce98b..974c759 100644 --- a/ExSwift/String.swift +++ b/ExSwift/String.swift @@ -51,6 +51,18 @@ extension String { } + /** + * Returns an array of strings, each of which is a substring of self formed by splitting it on separator + * @param separator + * @return Array of strings + */ + func explode (separator: Character) -> String[] { + return split(self, { + (element: Character) -> Bool in + return element == separator + }) + } + /** * Random string * @param length String length, 0 -> random length diff --git a/ExSwiftTests/ExSwiftArrayTests.swift b/ExSwiftTests/ExSwiftArrayTests.swift index 4d33aca..add7a93 100644 --- a/ExSwiftTests/ExSwiftArrayTests.swift +++ b/ExSwiftTests/ExSwiftArrayTests.swift @@ -187,6 +187,30 @@ class ExtensionsArrayTests: XCTestCase { XCTAssert(Array(group[true]!) == [4, 5]) XCTAssert(Array(group[false]!) == [1, 2, 3]) } + + func testReduceRight () { + let list = [[0, 1], [2, 3], [4, 5]]; + let flat = list.reduceRight(Array(), { return $0 + $1 }); + XCTAssert(flat == [4, 5, 2, 3, 0, 1]) + } + + func testImplode () { + XCTAssert(["A", "B", "C"].implode("A") == "AABAC") + } + + func testPluck () { + + let values = [ + ["Name": "Bob", "Score": 6], + ["Name": "Tim", "Score": 8] + ] + + let result = values.pluck("Score") as Int[] + + println(result) + + } + /* func testPerformanceExample() { // This is an example of a performance test case. @@ -194,5 +218,5 @@ class ExtensionsArrayTests: XCTestCase { } }*/ - + } diff --git a/ExSwiftTests/ExSwiftDictionaryTests.swift b/ExSwiftTests/ExSwiftDictionaryTests.swift index ebbb73f..69c31b1 100644 --- a/ExSwiftTests/ExSwiftDictionaryTests.swift +++ b/ExSwiftTests/ExSwiftDictionaryTests.swift @@ -96,4 +96,16 @@ class ExSwiftDictionaryTests: XCTestCase { XCTAssertFalse(all) } + func testReduce () { + + let reduced = dictionary.reduce(Dictionary(), { + (var initial: Dictionary, couple: (String, Int)) in + initial.updateValue(couple.0, forKey: couple.1) + return initial + }) + + XCTAssert(reduced == [2: "B", 3: "C", 1: "A"]) + + } + } diff --git a/ExSwiftTests/ExSwiftStringTests.swift b/ExSwiftTests/ExSwiftStringTests.swift index c5e8205..edc2d5c 100644 --- a/ExSwiftTests/ExSwiftStringTests.swift +++ b/ExSwiftTests/ExSwiftStringTests.swift @@ -33,4 +33,11 @@ class ExSwiftStringTests: XCTestCase { } + func testExplode () { + + let string = "A B C" + XCTAssert(string.explode(" ") == ["A", "B", "C"]) + + } + } diff --git a/Examples/Array.md b/Examples/Array.md index aaf3934..aab4075 100644 --- a/Examples/Array.md +++ b/Examples/Array.md @@ -30,6 +30,8 @@ - [`shift`](#shift) - [`unshift`](#unshift) - [`groupBy`](#groupby) + - [`reduceRight`](#reduceright) + - [`implode`](#implode) - [Class Methods](#class-methods) - [`range`](#range) - [Operators](#operators) @@ -261,6 +263,19 @@ let group = array.groupBy(groupingFunction: { // → [true: [5, 6], false: [1, 2, 3]] ``` +##### `reduceRight` ##### +``` +let list = [[0, 1], [2, 3], [4, 5]]; +list.reduceRight(Array(), { return $0 + $1 }); +// → [4, 5, 2, 3, 0, 1] +``` + +##### `implode` ##### +``` +["A", "B", "C"].implode("_") +// → A_B_C +``` + ### Class Methods ### ##### `range` ##### diff --git a/Examples/Dictionary.md b/Examples/Dictionary.md index 2bc94f3..90b61b2 100644 --- a/Examples/Dictionary.md +++ b/Examples/Dictionary.md @@ -14,6 +14,7 @@ - [`groupBy`](#groupby) - [`all`](#all) - [`any`](#any) + - [`reduce`](#reduce) ### Instance Methods ### @@ -113,3 +114,13 @@ dictionary.all { // → false ``` +#### `reduce` #### +```swift +let dictionary = [ "A": 1, "B": 2, "C": 3 ] +let reduced = dictionary.reduce(Dictionary(), { + (var initial: Dictionary, couple: (String, Int)) in + initial.updateValue(couple.0, forKey: couple.1) + return initial +}) +// → [2: "B", 3: "C", 1: "A"] +``` diff --git a/Examples/String.md b/Examples/String.md index 1244d58..e2e80c6 100644 --- a/Examples/String.md +++ b/Examples/String.md @@ -4,7 +4,8 @@ - [String](#string) - [Instance Methods](#instance-methods) - - [`length`](#times) + - [`length`](#length) + - [`explode`](#explode) - [Class Methods](#class-methods) - [`random`](#random) - [Operators](#operators) @@ -20,6 +21,13 @@ // → 2 ``` +##### `explode` ##### +``` +let string = "A B C" +string.explode(" ") +// → ["A", "B", "C"] +``` + ### Class Methods ### ##### `random` ##### diff --git a/README.md b/README.md index a087cc8..866b77c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # ExSwift -JavaScript inspired (lo-dash, underscore) set of Swift extensions for standard types, functions and classes. +JavaScript (Lo-Dash, Underscore) & Ruby inspired set of Swift extensions for standard types and classes. ## Contents ## @@ -57,6 +57,8 @@ Name | Signature **`shift`**|`shift() -> T` **`unshift`**|`unshift(newElement: T)` **`groupBy`**|`groupBy (groupingFunction group: (T) -> (U)) -> Dictionary>` +**`reduceRight`**|`reduceRight (initial: U, combine: (U, Element) -> U) -> U` +**`implode`**|`implode (separator: C) -> C?` ##### Class Methods ##### @@ -114,6 +116,7 @@ Examples in [Examples/String.md](Examples/String.md) Name | Signature ---- | --------- **`length`**|`length () -> Int` +**`explode`**|`explode (separator: Character) -> String[]` ##### Class Methods ##### @@ -159,6 +162,7 @@ Name | Signatures **`groupBy`**|`groupBy (groupingFunction group: (KeyType, ValueType) -> (T)) -> Dictionary>` **`any`**|`any (test: (KeyType, ValueType) -> (Bool)) -> Bool` **`all`**|`all (test: (KeyType, ValueType) -> (Bool)) -> Bool` +**`reduce`**|`reduce (initial: U, combine: (U, Element) -> U) -> U` ### To Do ### * Compile as library as soon as XCode 6 stops crashing.