Skip to content

Commit

Permalink
Added Dictionary.mapKeys and Dictionary.compactMapKeys
Browse files Browse the repository at this point in the history
Fixes [CSDK-105].

This came up in #1534 (comment) and will simplify some of the code in #1727.
  • Loading branch information
NachoSoto committed Jun 23, 2022
1 parent e1d1a2b commit 8cc9ca0
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 3 deletions.
20 changes: 20 additions & 0 deletions Sources/FoundationExtensions/Dictionary+Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,26 @@ extension Dictionary {

}

extension Dictionary {

func mapKeys<NewKey: Hashable>(_ transformer: (Key) -> NewKey) -> [NewKey: Value] {
return self.compactMapKeys(transformer)
}

func compactMapKeys<NewKey: Hashable>(_ transformer: (Key) -> NewKey?) -> [NewKey: Value] {
var result = [NewKey: Value](minimumCapacity: self.count)

for (key, value) in self {
if let newKey = transformer(key) {
result.updateValue(value, forKey: newKey)
}
}

return result
}

}

extension Sequence {

/// Creates a `Dictionary` with the values in the receiver sequence, and the keys provided by `key`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,11 @@ class DictionaryExtensionsTests: TestCase {
}
}

func testMergeDictionariesWithMergeStrategyKeepOriginalValue() {
}

class DictionaryExtensionsMergingTests: TestCase {

func testMergeStrategyKeepOriginalValue() {
let dict = ["a": "1", "b": "1"]
let dict2 = ["a": "2", "b": "2", "c": "2"]
let expectedDict = ["a": "1", "b": "1", "c": "2"]
Expand All @@ -54,7 +58,7 @@ class DictionaryExtensionsTests: TestCase {
expect(obtainedDict).to(equal(expectedDict))
}

func testMergeDictionariesWithMergeStrategyOverwriteValue() {
func testMergeStrategyOverwriteValue() {
let dict = ["a": "1", "b": "1"]
let dict2 = ["a": "2", "b": "2", "c": "2"]
let expectedDict = ["a": "2", "b": "2", "c": "2"]
Expand All @@ -65,7 +69,7 @@ class DictionaryExtensionsTests: TestCase {
expect(obtainedDict).to(equal(expectedDict))
}

func testMergeDictionariesWithDefaultMergeStrategy() {
func testDefaultMergeStrategy() {
let dict = ["a": "1", "b": "1"]
let dict2 = ["a": "2", "b": "2", "c": "2"]
let expectedDict = ["a": "2", "b": "2", "c": "2"]
Expand Down Expand Up @@ -98,6 +102,11 @@ class DictionaryExtensionsTests: TestCase {
expect(original).to(equal(expectedDict))
}

}

// swiftlint:disable:next type_name
class DictionaryExtensionsDictionaryWithKeysTests: TestCase {

func testCreatingDictionaryWithNoValues() {
expect([String]().dictionaryWithKeys { $0 }) == [:]
}
Expand Down Expand Up @@ -133,4 +142,87 @@ class DictionaryExtensionsTests: TestCase {
3: "3"
]
}

}

class DictionaryExtensionsMapKeysTests: TestCase {

private typealias Input = [Int: Int]
private typealias Output = [String: Int]

private let transformer: (Int) -> String = { String($0) }

func testMapEmptyDictionary() {
expect(Input().mapKeys(self.transformer)) == [:]
}

func testMapDictionaryWithOneKey() {
expect([1: "test"].mapKeys(self.transformer)) == [
"1": "test"
]
}

func testMapDictionary() {
let input: Input = [
1: 1,
2: 2,
3: 3
]
expect(input.mapKeys(self.transformer)) == [
"1": 1,
"2": 2,
"3": 3
]
}

func tetMapKeysWithOverlappingKeys() {
let input: [String: Int] = [
"a1": 1,
"a2": 2,
"b3": 3
]

let output = input.mapKeys { String($0.prefix(1)) }
expect(output).to(haveCount(2))
expect(output["b"]) == 3
expect(output["a"]).to(satisfyAnyOf(
equal(1),
equal(2)
))
}

func testCompactMapEmptyDictionary() {
expect(Input().compactMapKeys(self.transformer)) == [:]
}

func testCompactMapDictionaryWithOneKey() {
expect([1: "test"].compactMapKeys(self.transformer)) == [
"1": "test"
]
}

func testCompactMapDictionaryResultingInEmptyDictionary() {
expect([1: "test"].compactMapKeys { _ in nil }) == [:]
}

func tetCompactMapKeys() {
let input: [Int: Int] = [
1: 1,
2: 2,
3: 3,
4: 4,
5: 5
]

let output = input.compactMapKeys {
$0.isMultiple(of: 2)
? String($0)
: nil
}
expect(output) == [
2: 2,
4: 4
]
}

}

0 comments on commit 8cc9ca0

Please sign in to comment.