[SWIFT] map, compactMap und flatMap

Einführung

Es gibt "Karte" als typische Operation für Sammlungen und sogenannte "Leute mit Werten in etwas". Es gibt jedoch Varianten von "Karte" und es ist leicht zu verwechseln, deshalb möchte ich sie organisieren.

In diesem Artikel wird ein Array als Beispiel verwendet. In der Tat bieten Arrays, Wörterbücher und optionale "Container" ähnliche Operationen (wenn auch nicht genau gleich).

Kartentyp

map Transformiert jedes Element im Array. Da alle Elemente konvertiert werden, ändert sich die Anzahl der Elemente vor und nach der Konvertierung nicht.

map.png

compactMap Entspricht "map", schließt jedoch "nil" aus den Elementen aus und packt optional aus. Da "Null" ausgeschlossen ist, kann sich die Anzahl der Elemente vor und nach der Konvertierung im Gegensatz zu "Karte" ändern (verringern).

compactMap.png

flatMap Wenn das Array verschachtelt ist, extrahieren Sie die Elemente aus dem inneren Array, um es zu einem flachen Array zu machen (zweidimensionales Array-> eindimensionales Array).

flatMap1.png

Wenn Sie sich den inneren "** Container ** namens Array" als "** Container ** namens Optional" vorstellen, erstellen Sie ein "Array mit dem Inhalt von Optional extrahiert", was der gleichen Operation wie "compactMap" entspricht.

--Array <Array <Element >> - (Konvertierung) ->Array <Element> --Array <Optional <Element >> - (Konvertierung) ->Array <Element>

flatMap2.png

Zu diesem Zweck wurden auch frühe Versionen von Swift verwendet, die "compactMap" nicht implementiert haben, sind aber jetzt veraltet. Lassen Sie uns "compactMap" gehorsam verwenden.

Stichprobe

Dies ist ein Beispiel mit "map", "compactMap", "flatMap". Bitte lesen Sie es, während Sie es mit den obigen vier Zahlen vergleichen.

Codebeispiel

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)

      """
)

Ausführungsergebnis

== 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]]

Zusammenfassung

Es ist leicht, "Karte" in einem Diagramm zu verstehen. Operationen hier werden häufig im Combine-Framework verwendet, daher denke ich, dass es sehr einfach zu entwickeln ist, wenn Sie es beherrschen.

Recommended Posts

map, compactMap und flatMap
Unterschied zwischen Stream Map und FlatMap
Zum Verständnis von Karte und Flatmap in Stream (1)
Verwenden Sie den schnellen Filter und die Karte
[Rubiy] Vereinfache jedes mit Map und Inject
Versuchen Sie, Scala-ähnliche Optionstyp-Musterübereinstimmung und Map FlatMap in Java zu realisieren