Enum ist ein sehr nützliches Modul, das eine Reihe von Algorithmen für die Arbeit mit Enumerables bereitstellt. Es bietet Sortieren, Filtern, Gruppieren, Zählen, Suchen, das Finden von Minimal- und Maximalwerten und vieles mehr.
Im Allgemeinen ist ein Enumerable jede Art von Daten, über die iteriert werden kann, also eine Sammlung. In Elixir ist ein Enumerable jeder Datentyp, der das Protokoll Enumerable implementiert. Die häufigsten davon sind Listen und Maps.
Viele Funktionen von Enum akzeptieren eine Funktion als Argument.
Enum.all?([1, 2, 3, 4, 5], fn x -> x > 3 end)
# => false
Die häufigsten Funktionen von Enum sind map und reduce.
map/2Mit Enum.map/2 kannst du jedes Element in einem Enumerable durch ein anderes Element ersetzen. Das zweite Argument von Enum.map/2 ist eine Funktion, die das ursprüngliche Element entgegennimmt und dessen Ersatz zurückgibt.
reduce/3Mit Enum.reduce/3 kannst du das gesamte Enumerable zu einem einzigen Wert reduzieren. Dazu wird eine spezielle Variable namens Akkumulator verwendet. Der Akkumulator trägt den Zwischenzustand der Reduktion zwischen den Iterationen.
Das zweite Argument von Enum.reduce/3 ist der Anfangswert des Akkumulators. Das dritte Argument ist eine Funktion, die ein Element und einen Akkumulator entgegennimmt und den neuen Wert für den Akkumulator zurückgibt.
Wenn du Maps mit Enum-Funktionen verwendest, wird die Map automatisch in eine Liste aus 2 {key, value}-Tupeln umgewandelt.
Um sie wieder in eine Map umzuwandeln, verwendest du Enum.into/2. Enum.into/2 ist eine Funktion, die ein Enumerable in ein Collectable umwandelt, also eine beliebige Datenstruktur, die das Protokoll Collectable implementiert. Man kann sie sich als das Gegenteil von Enum.reduce/3 vorstellen.
Enum hat auch Enum.into/3. Enum.into/3 ist eine Variante von Enum.into/2, die eine Transformationsfunktion entgegennimmt, die angewendet wird, während das Enumerable in ein Collectable umgewandelt wird.
Anstatt Enum.into/3 oder Enum.map/2 plus Enum.into/2 zu verwenden, um eine Transformation (ein Mapping) auf eine Map anzuwenden, können wir auch die spezielle Funktion Map.new/2 verwenden. Sie funktioniert genau wie Enum.into/3, indem sie ein Enumerable und eine Transformationsfunktion entgegennimmt, aber sie gibt immer eine neue Map zurück, statt uns die Wahl des Collectables zu überlassen.
Du betreibst eine Online-Boutique für Mode. Dein großer Ausverkauf steht kurz bevor, also musst du deinen Bestand überprüfen, um sicherzugehen, dass du bereit bist.
Ein einzelner Artikel im Bestand wird durch eine Map dargestellt, und der gesamte Bestand ist eine Liste solcher Maps.
%{
name: "White Shirt",
price: 40,
quantity_by_size: %{s: 3, m: 7, l: 8, xl: 4}
}
Implementiere die Funktion sort_by_price/1. Sie soll den Bestand entgegennehmen und ihn nach dem Artikelpreis aufsteigend sortiert zurückgeben.
BoutiqueInventory.sort_by_price([
%{price: 65, name: "Maxi Brown Dress", quantity_by_size: %{}},
%{price: 50, name: "Red Short Skirt", quantity_by_size: %{}},
%{price: 50, name: "Black Short Skirt", quantity_by_size: %{}},
%{price: 20, name: "Bamboo Socks Cats", quantity_by_size: %{}}
])
# => [
# %{price: 20, name: "Bamboo Socks Cats", quantity_by_size: %{}},
# %{price: 50, name: "Red Short Skirt", quantity_by_size: %{}},
# %{price: 50, name: "Black Short Skirt", quantity_by_size: %{}},
# %{price: 65, name: "Maxi Brown Dress", price: 65, quantity_by_size: %{}}
# ]
Nachdem du deinen Bestand nach dem Preis sortiert hast, ist dir aufgefallen, dass du beim Erfassen des Bestands einen Fehler gemacht haben musst und vergessen hast, für ein paar Artikel die Preise einzutragen.
Implementiere die Funktion with_missing_price/1. Sie soll den Bestand entgegennehmen und eine Liste der Artikel zurückgeben, die keinen Preis haben.
BoutiqueInventory.with_missing_price([
%{price: 40, name: "Black T-shirt", quantity_by_size: %{}},
%{price: nil, name: "Denim Pants", quantity_by_size: %{}},
%{price: nil, name: "Denim Skirt", quantity_by_size: %{}},
%{price: 40, name: "Orange T-shirt", quantity_by_size: %{}}
])
# => [
# %{price: nil, name: "Denim Pants", quantity_by_size: %{}},
# %{price: nil, name: "Denim Skirt", quantity_by_size: %{}}
# ]
Dir ist aufgefallen, dass in einigen Artikelnamen ein Wort vorkommt, das du nicht mehr verwenden möchtest. Jetzt musst du alle Artikelnamen mit diesem Wort aktualisieren.
Implementiere die Funktion update_names/3. Sie soll den Bestand, das alte Wort, das du entfernen möchtest, und ein neues Wort, das du stattdessen verwenden möchtest, entgegennehmen. Sie soll eine Liste der Artikel mit aktualisierten Namen zurückgeben.
BoutiqueInventory.update_names(
[
%{price: 40, name: "Black T-shirt", quantity_by_size: %{}},
%{price: 70, name: "Denim Pants", quantity_by_size: %{}},
%{price: 65, name: "Denim Skirt", quantity_by_size: %{}},
%{price: 40, name: "Orange T-shirt", quantity_by_size: %{}}
],
"T-shirt",
"Tee"
)
# => [
# %{price: 40, name: "Black Tee", quantity_by_size: %{}},
# %{price: 70, name: "Denim Pants", quantity_by_size: %{}},
# %{price: 65, name: "Denim Skirt", quantity_by_size: %{}},
# %{price: 40, name: "Orange Tee", quantity_by_size: %{}}
# ]
Einige Artikel verkauften sich besonders gut, also hast du mehr nachbestellt, in allen Größen.
Implementiere die Funktion increase_quantity/2. Sie soll einen einzelnen Artikel und eine Zahl n entgegennehmen und diesen Artikel zurückgeben, wobei die Menge für jede Größe um n erhöht wurde.
BoutiqueInventory.increase_quantity(
%{
name: "Polka Dot Skirt",
price: 68,
quantity_by_size: %{s: 3, m: 5, l: 3, xl: 4}
},
6
)
# => %{
# name: "Polka Dot Skirt",
# price: 68,
# quantity_by_size: %{l: 9, m: 11, s: 9, xl: 10}
# }
Um zu wissen, wie viel Platz du in deinem Lager brauchst, musst du wissen, wie viele Stücke du von jedem Artikel insgesamt hast.
Implementiere die Funktion total_quantity/1. Sie soll einen einzelnen Artikel entgegennehmen und zurückgeben, wie viele Stücke du insgesamt hast, egal in welcher Größe.
BoutiqueInventory.total_quantity(%{
name: "Red Shirt",
price: 62,
quantity_by_size: %{s: 3, m: 6, l: 5, xl: 2}
})
# => 16
Melde dich bei Exercism an, um Elixir mit 58 Konzepte168 Übungen und echtem menschlichen Mentoring zu lernen und zu meistern, alles kostenlos.