diff --git a/ExSwift.xcodeproj/project.xcworkspace/xcuserdata/pie.xcuserdatad/UserInterfaceState.xcuserstate b/ExSwift.xcodeproj/project.xcworkspace/xcuserdata/pie.xcuserdatad/UserInterfaceState.xcuserstate index 75d482d..93b6c3d 100644 Binary files a/ExSwift.xcodeproj/project.xcworkspace/xcuserdata/pie.xcuserdatad/UserInterfaceState.xcuserstate and b/ExSwift.xcodeproj/project.xcworkspace/xcuserdata/pie.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/ExSwift/Array.swift b/ExSwift/Array.swift index 7d347d0..343f0d6 100644 --- a/ExSwift/Array.swift +++ b/ExSwift/Array.swift @@ -174,21 +174,16 @@ extension Array { var result = Array>() // 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.