Треки
/
Elixir
Elixir
/
Вправи
/
Інвентар бутіка
Інвентар бутіка

Інвентар бутіка

Навчальна вправа

Вступ

Enum

Enum - це дуже корисний модуль, який надає набір алгоритмів для роботи з перелічуваними. Він уміє сортувати, фільтрувати, групувати, рахувати, шукати, знаходити мінімальні й максимальні значення та багато іншого.

Загалом перелічуване - це будь-які дані, які можна перебрати, тобто певна сукупність. В Elixir перелічуваним є будь-який тип даних, який реалізує протокол Enumerable. Найпоширеніші з них - це масиви і словники.

Багато функцій Enum приймають функцію як аргумент.

Enum.all?([1, 2, 3, 4, 5], fn x -> x > 3 end)
# => false

Найпоширеніші функції Enum - це map і reduce.

map/2

Enum.map/2 дає змогу замінити кожен елемент у перелічуваному на інший елемент. Другий аргумент Enum.map/2 - це функція, яка приймає початковий елемент і повертає його заміну.

reduce/3

Enum.reduce/3 дає змогу звести все перелічуване до одного значення. Для цього використовується спеціальна змінна, яку називають акумулятором. Акумулятор зберігає проміжний стан зведення між ітераціями.

Другий аргумент Enum.reduce/3 - це початкове значення акумулятора. Третій аргумент - це функція, яка приймає елемент та акумулятор і повертає нове значення акумулятора.

Робота зі словниками

Коли ми використовуємо словники з функціями Enum, словник автоматично перетворюється на масив із двох кортежів {key, value}.

Щоб перетворити його назад у словник, використаймо Enum.into/2. Enum.into/2 - це функція, яка перетворює перелічуване в колекцію, тобто в будь-яку структуру даних, що реалізує протокол Collectable. Її можна вважати протилежністю Enum.reduce/3.

У Enum також є Enum.into/3. Enum.into/3 - це варіант Enum.into/2, який приймає функцію перетворення, що застосовується під час перетворення перелічуваного в колекцію.

Перетворення словників

Замість того щоб використовувати Enum.into/3, або Enum.map/2 разом із Enum.into/2, для застосування перетворення (відображення) до словника, можна також скористатися спеціальною функцією Map.new/2. Вона працює точно так само, як Enum.into/3: приймає перелічуване і функцію перетворення, але завжди повертає новий словник, а не дає нам обрати колекцію.

Вказівки

Ми керуємо онлайн-бутиком модного одягу. Наближається наш великий щорічний розпродаж, тож потрібно перевірити інвентар, щоб переконатися, що ми готові.

Один товар в інвентарі представлено мапою, а весь інвентар - це список таких мап.

%{
  name: "White Shirt",
  price: 40,
  quantity_by_size: %{s: 3, m: 7, l: 8, xl: 4}
}

1. Відсортувати товари за ціною

Реалізуйте функцію sort_by_price/1. Вона приймає інвентар і повертає його, відсортований за ціною товару за зростанням.

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: %{}}
#    ]

2. Знайти всі товари без ціни

Після сортування інвентарю за ціною ми помітили, що, мабуть, припустилися помилки, коли проводили інвентаризацію, і забули вказати ціни для кількох товарів.

Реалізуйте функцію with_missing_price/1. Вона приймає інвентар і повертає список товарів, у яких немає ціни.

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: %{}}
#    ]

3. Оновити назви товарів

Ми помітили, що в назвах деяких товарів є слово, яке ми більше не хочемо використовувати. Тепер потрібно оновити всі назви товарів із цим словом.

Реалізуйте функцію update_names/3. Вона приймає інвентар, старе слово, яке потрібно прибрати, і нове слово, яке потрібно використати замість нього. Вона повертає список товарів з оновленими назвами.

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: %{}}
#    ]

4. Збільшити кількість товару

Деякі товари продавалися особливо добре, тож ми замовили більше, у всіх розмірах.

Реалізуйте функцію increase_quantity/2. Вона приймає один товар і число n та повертає цей товар, у якому кількість для кожного розміру збільшено на n.

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}
#    }

5. Обчислити загальну кількість товару

Щоб знати, скільки місця потрібно на складі, потрібно знати, скільки всього одиниць кожного товару ми маємо.

Реалізуйте функцію total_quantity/1. Вона приймає один товар і повертає, скільки всього одиниць цього товару ми маємо в усіх розмірах разом.

BoutiqueInventory.total_quantity(%{
  name: "Red Shirt",
  price: 62,
  quantity_by_size: %{s: 3, m: 6, l: 5, xl: 2}
})

# => 16
Редагувати через GitHub Посилання відкривається в новому вікні або вкладці
Elixir Exercism

Час розпочати Інвентар бутіка?

Зареєструйтеся на Exercism, щоб вивчати й опановувати Elixir, а також 58 концепцій168 вправ та справжнє наставництво від людей, і все це безкоштовно.