Small Swift Tips #01: Grouping elements using group:by:

For the very first SmallSwiftTips I will start with a very handy new Dictionary init that is init(grouping:by:)

This new init was introduced on Swift 4 and it helps creating a new grouped Dictionary. It takes a Sequence and a closure as input.

let frameworks = ["UIKit", "CoreMedia", "Security", "MapKit", "StoreKit"]
let frameworksFirstLetters = Dictionary(grouping: frameworks, by: { $0.first! })
//["U": ["UIKit"], "M": ["MapKit"], "C": ["CoreMedia"], "S": ["Security", "StoreKit"]]

let frameworksWithCoreOnName = Dictionary(grouping: frameworks, by: { $0.contains("Core") })
//[false: ["UIKit", "Security", "MapKit", "StoreKit"], true: ["CoreMedia"]]

Note that the key for this new Dictionary will be the result from the closure. In the first example, the closure's result is a Character, so we'll have a new [Character: [String]] Dictionary. On the second example we have a Bool value in the closure's result, giving us a new [Bool: [String]].

You can use a sequence of custom objects as well.

enum AssetType {
    case image
    case video
}

struct Asset {
    let type: AssetType
    let name: String
}

let assets = [
    Asset(type: .image, name: "icon"),
    Asset(type: .video, name: "apple-watch-intro-video"),
    Asset(type: .image, name: "new-footer")
]

let group = Dictionary(grouping: assets, by: { $0.type })
//[AssetType.image: [Asset, Asset], AssetType.video: [Asset]]

This code will return a new [AssetType: [Asset]] which is really handy. This can be very helpful and I hope you liked and use it. 😁🚀