Dies ist eine ergänzende Antwort zur Erläuterung von Karten und Falzen. Für die folgenden Beispiele verwende ich diese Liste. Denken Sie daran, dass diese Liste unveränderlich ist und sich daher niemals ändern wird:
var numbers = [1, 2, 3, 4, 5]
In meinen Beispielen verwende ich Zahlen, da sie zu leicht lesbarem Code führen. Denken Sie jedoch daran, dass Falten für alles verwendet werden können, wofür eine traditionelle imperative Schleife verwendet werden kann.
Eine Map nimmt eine Liste von etwas und eine Funktion und gibt eine Liste zurück, die mit der Funktion geändert wurde. Jedes Element wird an die Funktion übergeben und wird zu dem, was die Funktion zurückgibt.
Das einfachste Beispiel hierfür ist das Hinzufügen einer Nummer zu jeder Nummer in einer Liste. Ich werde Pseudocode verwenden, um es sprachunabhängig zu machen:
function add-two(n):
return n + 2
var numbers2 =
map(add-two, numbers)
Wenn Sie drucken numbers2
, sehen Sie, [3, 4, 5, 6, 7]
welches die erste Liste ist, bei der jedem Element 2 hinzugefügt wurden. Beachten Sie, dass die zu verwendende Funktion add-two
angegeben wurde map
.
Fold s sind ähnlich, außer dass die Funktion, die Sie ihnen geben müssen, 2 Argumente annehmen muss. Das erste Argument ist in der Regel der Akkumulator (in einer linken Falte, die am häufigsten sind). Der Akkumulator sind die Daten, die beim Schleifen übertragen werden. Das zweite Argument ist das aktuelle Element der Liste. genau wie oben für die map
Funktion.
function add-together(n1, n2):
return n1 + n2
var sum =
fold(add-together, 0, numbers)
Wenn Sie drucken sum
, sehen Sie die Summe der Zahlen: 15.
Hier sind die Argumente fold
dafür:
Dies ist die Funktion, die wir geben die Falte. Die Falte übergibt die Funktion dem aktuellen Akkumulator und dem aktuellen Element der Liste. Was auch immer die Funktion zurückgibt, wird der neue Akku, der beim nächsten Mal an die Funktion übergeben wird. Auf diese Weise "merken" Sie sich Werte, wenn Sie einen Loop im FP-Stil erstellen. Ich habe ihm eine Funktion gegeben, die 2 Zahlen annimmt und sie hinzufügt.
Dies ist der anfängliche Akkumulator. Wie der Akku startet, bevor Elemente in der Liste verarbeitet werden. Wenn Sie Zahlen summieren, wie hoch ist die Gesamtsumme, bevor Sie Zahlen addieren? 0, die ich als zweites Argument übergeben habe.
Schließlich übergeben wir wie bei der Karte auch die Liste der zu verarbeitenden Nummern.
Wenn Falten immer noch keinen Sinn ergeben, ziehen Sie dies in Betracht. Wenn du schreibst:
# Notice I passed the plus operator directly this time,
# instead of wrapping it in another function.
fold(+, 0, numbers)
Sie setzen im Grunde die übergebene Funktion zwischen die einzelnen Elemente in der Liste und fügen den anfänglichen Akkumulator entweder links oder rechts hinzu (je nachdem, ob es sich um eine linke oder eine rechte Falte handelt).
[1, 2, 3, 4, 5]
Wird:
0 + 1 + 2 + 3 + 4 + 5
^ Note the initial accumulator being added onto the left (for a left fold).
Welches entspricht 15.
Verwenden Sie ein, map
wenn Sie eine Liste in eine andere Liste gleicher Länge umwandeln möchten.
Verwenden Sie a, fold
wenn Sie eine Liste in einen einzelnen Wert umwandeln möchten, z. B. eine Liste von Zahlen summieren.
Wie @Jorg in den Kommentaren betonte, muss der "Einzelwert" nicht einfach wie eine Zahl sein. es kann sich um ein einzelnes Objekt handeln, einschließlich einer Liste oder eines Tupels! Die Art und Weise, wie ich tatsächlich Falten hatte, bestand darin, eine Karte in Form einer Falte zu definieren . Beachten Sie, wie der Akku eine Liste ist:
function map(f, list):
fold(
function(xs, x): # xs is the list that has been processed so far
xs.add( f(x) ) # Add returns the list instead of mutating it
, [] # Before any of the list has been processed, we have an empty list
, list)
Ehrlich gesagt, wenn Sie erst einmal verstanden haben, werden Sie feststellen, dass fast jede Schleife durch eine Falte oder eine Karte ersetzt werden kann.