Skip to content

Commit

Permalink
Create mapping functions for Dictionary (SwifterSwift#546)
Browse files Browse the repository at this point in the history
* Create `map` and `compactMap` functions for `Dictionary` that return a new `Dictionary`, rather than an `Array`.

* Change method names to avoid clashing with the built in `map` and `compactMap` functions.
  • Loading branch information
guykogus authored Aug 16, 2018
1 parent fb19497 commit 9eb6259
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ The changelog for **SwifterSwift**. Also see the [releases](https://github.com/S
- `beginRefresh(in tableView:, animated:, sendAction:)` UIRefreshControl extension to begin refresh programatically. [#525](https://github.com/SwifterSwift/SwifterSwift/pull/525) by [ratulSharker](https://github.com/ratulSharker)
- **Dictionary**:
- Added `removeValueForRandomKey()` to remove a value for a random key from a dictionary. [#497](https://github.com/SwifterSwift/SwifterSwift/pull/497) by [vyax](https://github.com/vyax).
- Added `mapKeysAndValues(_:)` to map a `Dictionary` into a `Dictionary` with different (or same) `Key` and `Value` types. [#546](https://github.com/SwifterSwift/SwifterSwift/pull/546) by [guykogus](https://github.com/guykogus)
- Added `compactMapKeysAndValues(_:)` to map a `Dictionary` into a `Dictionary`, excluding `nil` results, with different (or same) `Key` and `Value` types. [#546](https://github.com/SwifterSwift/SwifterSwift/pull/546) by [guykogus](https://github.com/guykogus)
- **RangeReplaceableCollection**:
- Added `removeRandomElement()` to remove a random element from a collection. [#497](https://github.com/SwifterSwift/SwifterSwift/pull/497) by [vyax](https://github.com/vyax).
- **UIView**
Expand Down
17 changes: 17 additions & 0 deletions Sources/Extensions/SwiftStdlib/DictionaryExtensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -177,3 +177,20 @@ public extension Dictionary {
}

}

extension Dictionary {
/// SwifterSwift: Returns a dictionary containing the results of mapping the given closure over the sequence’s elements.
/// - Parameter transform: A mapping closure. `transform` accepts an element of this sequence as its parameter and returns a transformed value of the same or of a different type.
/// - Returns: A dictionary containing the transformed elements of this sequence.
func mapKeysAndValues<K, V>(_ transform: ((key: Key, value: Value)) throws -> (K, V)) rethrows -> [K: V] {
return [K: V](uniqueKeysWithValues: try map(transform))
}

/// SwifterSwift: Returns a dictionary containing the non-`nil` results of calling the given transformation with each element of this sequence.
/// - Parameter transform: A closure that accepts an element of this sequence as its argument and returns an optional value.
/// - Returns: A dictionary of the non-`nil` results of calling `transform` with each element of the sequence.
/// - Complexity: *O(m + n)*, where _m_ is the length of this sequence and _n_ is the length of the result.
func compactMapKeysAndValues<K, V>(_ transform: ((key: Key, value: Value)) throws -> (K, V)?) rethrows -> [K: V] {
return [K: V](uniqueKeysWithValues: try compactMap(transform))
}
}
32 changes: 32 additions & 0 deletions Tests/SwiftStdlibTests/DictionaryExtensionsTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -102,4 +102,36 @@ final class DictionaryExtensionsTests: XCTestCase {
XCTAssertFalse(dict.keys.contains("key2"))
}

func testMapKeysAndValues() {
let intToString = [0: "0", 1: "1", 2: "2", 3: "3", 4: "4", 5: "5", 6: "6", 7: "7", 8: "8", 9: "9"]

let stringToInt: [String: Int] = intToString.mapKeysAndValues { (key, value) in
return (String(describing: key), Int(value)!)
}

XCTAssertEqual(stringToInt, ["0": 0, "1": 1, "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8, "9": 9])
}

func testCompactMapKeysAndValues() {
// swiftlint:disable:next nesting
enum IntWord: String {
case zero
case one
case two
}

let strings = [
0: "zero",
1: "one",
2: "two",
3: "three"
]
let words: [String: IntWord] = strings.compactMapKeysAndValues { (key, value) in
guard let word = IntWord(rawValue: value) else { return nil }
return (String(describing: key), word)
}

XCTAssertEqual(words, ["0": .zero, "1": .one, "2": .two])
}

}

0 comments on commit 9eb6259

Please sign in to comment.