[SWIFT] map, compactMap et flatMap

introduction

Il y a map comme opération typique pour les collections et les soi-disant" gars avec des valeurs dans quelque chose ". Cependant, il existe des variantes de map et il est facile de se tromper, alors j'aimerais les organiser.

Dans cet article, un tableau est utilisé comme exemple. En fait, les tableaux, les dictionnaires et les "conteneurs" optionnels fournissent des opérations similaires (mais pas exactement les mêmes).

type de carte

map Transforme chaque élément du tableau. Puisque tous les éléments sont convertis, le nombre d'éléments ne change pas avant et après la conversion.

map.png

compactMap Identique à map, mais exclut nil des éléments et déballe Facultatif. Puisque «nil» est exclu, le nombre d'éléments peut changer (diminuer) avant et après la conversion contrairement à «map».

compactMap.png

flatMap Si le tableau est imbriqué, extrayez les éléments du tableau interne pour en faire un tableau plat (tableau bidimensionnel-> tableau unidimensionnel).

flatMap1.png

Si vous considérez le "** conteneur ** appelé tableau" interne comme un "** conteneur ** appelé facultatif", vous allez créer un "tableau avec le contenu de Optional extrait", qui est la même opération que compactMap.

--Array <Array <élément >> - (conversion) ->Array <element> --Array <Option <élément >> - (conversion) ->Array <element>

flatMap2.png

Les premières versions de Swift, qui n'implémentaient pas compactMap, étaient également utilisées à cette fin, mais sont maintenant obsolètes. Utilisons docilement compactMap.

échantillon

Ceci est un exemple utilisant map, compactMap, flatMap. Veuillez le lire en le comparant aux quatre chiffres ci-dessus.

Exemple de code

import Foundation

enum Category: String, CustomStringConvertible {
    var description: String {
        self.rawValue
    }

    case personal
    case business
}

struct Item: CustomStringConvertible {
    var description: String {
        """
        name: "\(self.name)", price: \(self.price), categories: \(self.categories ?? [])

        """
    }

    let name: String
    let price: Int
    let categories: [Category]?
}

let items: [Item] = [
    Item(name: "Suit", price: 15000, categories: [.business]),
    Item(name: "Pen", price: 400, categories: [.personal, .business]),
    Item(name: "Sea", price: 99999, categories: nil),
    Item(name: "Drink", price: 120, categories: [.personal]),
    Item(name: "Sky", price: 99999, categories:nil),
    Item(name: "Comic", price: 600, categories: [.personal])
]

print("""
      == Items ==========
      \(items)

      """
)

// map transforms each element in an Array.
let map = items.map { item in
    item.categories ?? []
}
print("""
      == map "item.categories ?? []" ==========
      \(map)

      """
)

// compactMap is a map that only collect non-nil values.
let compact = items.compactMap { item in
    item.categories
}
print("""
      == compactMap "item.categories" ==========
      \(compact)

      """
)

// flatMap flattens the inner Array.
let flat1 = items.flatMap { item in
    item.categories ?? []
}
print("""
      == flatMap "item.categories ?? []" ==========
      \(flat1)

      """
)

// This type of flatMap is deprecated. You should use compactMap.
let flat2 = items.flatMap { item in
    item.categories
}
print("""
      == flatMap "item.categories" ==========
      \(flat2)

      """
)

Résultat d'exécution

== Items ==========
[name: "Suit", price: 15000, categories: [business]
, name: "Pen", price: 400, categories: [personal, business]
, name: "Sea", price: 99999, categories: []
, name: "Drink", price: 120, categories: [personal]
, name: "Sky", price: 99999, categories: []
, name: "Comic", price: 600, categories: [personal]
]

== map "item.categories ?? []" ==========
[[business], [personal, business], [], [personal], [], [personal]]

== compactMap "item.categories" ==========
[[business], [personal, business], [personal], [personal]]

== flatMap "item.categories ?? []" ==========
[business, personal, business, personal, personal]

== flatMap "item.categories" ==========
[[business], [personal, business], [personal], [personal]]

Sommaire

Il est facile de comprendre la «carte» dans un diagramme. Les opérations ici sont souvent utilisées dans le framework Combine, donc je pense que ce sera très facile à développer si vous pouvez le maîtriser.

Recommended Posts

map, compactMap et flatMap
Différence entre Stream map et flatMap
Vers la compréhension de la carte et de la flatmap dans Stream (1)
Utilisez un filtre et une carte rapides
[Rubiy] Simplifiez chaque utilisation de la carte et injectez
Essayez de réaliser une correspondance de modèle de type Option de type Scala et une carte, flatMap en Java