iTranslated by AI
[Swift] Various Tips for Dictionaries
Introduction
In client-side code, using dictionaries generally carries the risk of nil values when accessing by key, and you cannot assign variable names to the value or key. For these reasons, it is usually better to define data structures using struct rather than declaring them as dictionaries.
Furthermore, the need to handle dictionaries has been significantly reduced by using Codable for API responses.
However, there are still times when using dictionaries is necessary, so I would like to share some useful tips for working with them.
Key Takeaways
- If you want to use both
keyandvalue-> Convert to a Struct early. - If you don't need to maintain the dictionary type -> Convert it as early as possible using
.valuesor.keys. - If you need to keep the dictionary type while processing -> Use
.mapValues(). -
.first(where: condition)can be used while keeping the dictionary type.
Converting to a Struct early when you need both key and value
While you can keep it as a dictionary, converting it to a struct allows you to assign variable names, giving meaning to both the key and the value.
let dict: [Int: String] = [1: "one", 2: "two" , 3: "three"]
struct Hoge {
let id: Int
let name: String
}
let hoges: [Hoge] = dict.map { key, value in Hoge(id: key, name: value) }
print(hoges) // [Hoge(id: 1, name: "one"), Hoge(id: 3, name: "three"), Hoge(id: 2, name: "two")]
- Note: Keep in mind that the order is not guaranteed.
Generating an array of just key or value -> .values or .keys
let dict: [Int: String] = [1: "one", 2: "two" , 3: "three"]
print(dict.keys) // [1, 3, 2]
print(dict.values) // ["one", "three", "two"]
// These produce the same results
print(dict.map(\.key)) // [1, 3, 2]
print(dict.map(\.value)) // ["one", "three", "two"]
- Note: Keep in mind that the order is not guaranteed.
Using .mapValues() to transform only the value while keeping the dictionary type
let dict: [Int: String] = [1: "one", 2: "two" , 3: "three"]
print(dict.mapValues { $0.count }) // [1: 3, 2: 3, 3: 5]
By using .values, .keys, or .mapValues(), you can handle dictionaries similarly to arrays, but it is good to keep the following in mind:
- If you need to keep the dictionary type while processing -> Perform the processing while maintaining the dictionary type ->
.mapValues() - If you don't need to maintain the dictionary type -> Convert the dictionary type at that stage ->
.valuesor.keys
.first(where: condition) can be used while keeping the dictionary type
let dict: [Int: String] = [1: "one", 2: "two" , 3: "three"]
// All of the following produce the same result
print(dict[2]!) // two
print(dict.first(where: { $0.key == 2 })!.value) // two
print(dict.first(where: { $0.value == "two" })!.value) // two
// You can also map to values first if you prefer
print(dict.map(\.value).first(where: { $0 == "two" })!) // two
It seems that you can perform most of the same operations on dictionaries as you can on arrays.
That is all.
Discussion