Last active
January 25, 2026 16:35
-
-
Save fxm90/3113ba447cc7275836591497a0c2ee47 to your computer and use it in GitHub Desktop.
Counterpart methods to `mapValues(_:)` and `compactMapValues(_:)`
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // | |
| // Dictionary+MapKeys.swift | |
| // | |
| // Created by Felix Mau on 14.06.21. | |
| // Copyright © 2021 Felix Mau. All rights reserved. | |
| // | |
| extension Dictionary { | |
| /// Returns a new dictionary with the keys transformed by the given closure | |
| /// and the original values. | |
| /// | |
| /// Use this method to transform the keys of a dictionary while keeping | |
| /// the associated values intact. Note that if the `transform` closure | |
| /// produces the same key for different original keys, the last key-value | |
| /// pair processed will overwrite previous ones. | |
| /// | |
| /// - Parameter transform: A closure that takes a key and value of the | |
| /// dictionary as its argument and returns a | |
| /// transformed key of type `T`. | |
| /// | |
| /// - Returns: A dictionary containing the transformed keys and the | |
| /// original values. | |
| /// | |
| /// - Complexity: O(*n*), where *n* is the length of the dictionary. | |
| func mapKeys<T: Hashable>(_ transform: (Key, Value) -> T) -> [T: Value] { | |
| reduce(into: [T: Value]()) { result, element in | |
| let mappedKey = transform(element.key, element.value) | |
| result[mappedKey] = element.value | |
| } | |
| } | |
| /// Returns a new dictionary containing only the non-`nil` keys produced | |
| /// by the given transformation, paired with the original values. | |
| /// | |
| /// Use this method to simultaneously transform and filter the keys of | |
| /// a dictionary. If `transform` returns `nil` for a key, that key-value | |
| /// pair is excluded from the resulting dictionary. | |
| /// | |
| /// - Parameter transform: A closure that takes a key and value of the | |
| /// dictionary as its argument and returns an | |
| /// optional transformed key of type `T?`. | |
| /// - Returns: A dictionary containing the non-`nil` transformed keys | |
| /// and the original values. | |
| /// | |
| /// - Complexity: O(*n*), where *n* is the length of the dictionary. | |
| func compactMapKeys<T: Hashable>(_ transform: (Key, Value) -> T?) -> [T: Value] { | |
| reduce(into: [T: Value]()) { result, element in | |
| guard let mappedKey = transform(element.key, element.value) else { | |
| return | |
| } | |
| result[mappedKey] = element.value | |
| } | |
| } | |
| } |
Author
Author
Unit-Tests for compaceMapKeys(_:)
import Testing
@Suite
struct DictionaryCompactMapKeysTests {
@Test
func compactMapKeys_shouldInvokeCallback_withCorrectKey_andValue() {
// Given
var receivedKey: Int?
var receivedValue: String?
let dictionary = [
1: "one",
]
// When
_ = dictionary.compactMapKeys { key, value in
receivedKey = key
receivedValue = value
return key
}
// Then
#expect(receivedKey == 1)
#expect(receivedValue == "one")
}
@Test
func compactMapKeys_shouldReturnDictionary_withMappedKeys_andOriginalValues() {
// Given
let dictionary = [
1: "one",
2: "two",
3: "three",
]
// When
let result = dictionary.compactMapKeys { key, _ in
key.isMultiple(of: 2)
? nil
: key * 2
}
// Then
let expectedDictionary = [
2: "one",
6: "three",
]
#expect(result == expectedDictionary)
}
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Unit-Tests for
mapKeys(_:)