У Elixir кортеж - це структура даних, яка впорядковує дані та містить фіксовану кількість елементів будь-якого типу, але без явних імен для кожного елемента. Кортежі в Elixir часто використовують для операцій, інтенсивних щодо читання памʼяті, адже доступ на читання до елемента має сталу часову складність. Їх зазвичай не використовують, коли елементи потрібно додавати чи вилучати динамічно, бо замість зміни наявного кортежу створюється новий, під який памʼять потрібно виділяти наперед.
На практиці кортежі в Elixir створюють за допомогою фігурних дужок. До елементів кортежу можна звертатися по одному за допомогою функції elem/2, використовуючи індексацію від нуля:
empty_tuple = {}
one_element_tuple = {1}
multiple_element_tuple = {1, :a, "hello"}
elem(multiple_element_tuple, 2)
# => "hello"
На практиці кортежі часто використовують, щоб подати згруповану інформацію.
Float.ratio(0.25)
# => {1, 4} indicating the numerator and denominator of the fraction ¼
Зіставлення зі зразком домінує в ідіоматичному коді Elixir, який спирається на твердження. Пригадаймо, що =/2 описано як оператор зіставлення, а не як оператор присвоєння. Коли ми використовуємо оператор зіставлення, то якщо зразок ліворуч збігається з правим, усі змінні ліворуч звʼязуються, а значення правої частини повертається. Якщо збігу немає, виникає MatchError.
2 = 2
# => 2
# Literals can be matched if they are the same
2 = 3
# => ** (MatchError) no match of right hand side value: 3
{_, denominator} = Float.ratio(0.25)
# => {1, 4}
# the variable `denominator` is bound to the value 4
Памʼятаймо, що зіставлення відбувається справа наліво.
В останньому прикладі, якщо змінна в зіставленні зі зразком нам не потрібна, ми можемо її відкинути, згадавши _. Будь-яку змінну, що починається з _, середовище виконання не відстежує.
Зіставлення зі зразком також стає в пригоді, коли ми створюємо функцію з кількома визначеннями. Його можна застосовувати до аргументів функції, і це визначає, яке визначення функції буде викликано: починаючи згори файлу й до першого збігу. Змінні можна звʼязати в голові функції та використати в тілі функції.
defmodule Example do
def named_function(:a = variable_a) do
{variable_a, 1}
end
def named_function(:b = variable_b) do
{variable_b, 2}
end
end
Example.named_function(:a)
# => {:a, 1}
Example.named_function(:b)
# => {:b, 2}
Example.named_function(:c)
# => ** (FunctionClauseError) no function clause matching in Example.named_function/1
Готуючись спекти печиво для друзів, ми виявили, що доведеться перевести деякі міри, використані в рецепті. Оскільки ми знайомі лише з метричною системою, потрібно придумати спосіб переводити поширені американські кулінарні міри в мілілітри (mL) для власної зручності.
Скористайтеся цією таблицею переведення у своєму рішенні:
| Unit to convert | volume | in milliliters (mL) |
|---|---|---|
| mL | 1 | 1 |
| US cup | 1 | 240 |
| US fluid ounce | 1 | 30 |
| US teaspoon | 1 | 5 |
| US tablespoon | 1 | 15 |
Як талановиті програмісти-початківці, ми вирішуємо використати мілілітри як проміжну одиницю, щоб спростити переведення з будь-якої наведеної одиниці в будь-яку іншу (навіть у ту саму).
Реалізуйте функцію KitchenCalculator.get_volume/1. Отримавши кортеж із парою обʼєму, вона повинна повернути лише числовий компонент.
KitchenCalculator.get_volume({:cup, 2.0})
# => 2.0
Реалізуйте функцію KitchenCalculator.to_milliliter/1. Отримавши кортеж із парою обʼєму, вона повинна перевести обʼєм у мілілітри за допомогою таблиці переведення.
Використайте кілька визначень функції та зіставлення зі зразком, щоб створити функції для кожної одиниці. Атоми, якими позначається кожна одиниця: :cup, :fluid_ounce, :teaspoon, :tablespoon, :milliliter. Поверніть результат переведення, загорнутий у кортеж.
KitchenCalculator.to_milliliter({:cup, 2.5})
# => {:milliliter, 600.0}
Реалізуйте функцію KitchenCalculator.from_milliliter/2. Отримавши кортеж із парою обʼєму та потрібну одиницю, вона повинна перевести обʼєм у потрібну одиницю за допомогою таблиці переведення.
Використайте кілька визначень функції та зіставлення зі зразком, щоб створити функції для кожної одиниці. Атоми, якими позначається кожна одиниця: :cup, :fluid_ounce, :teaspoon, :tablespoon, :milliliter
KitchenCalculator.from_milliliter({:milliliter, 1320.0}, :cup)
# => {:cup, 5.5}
Реалізуйте функцію KitchenCalculator.convert/2. Отримавши кортеж із парою обʼєму та потрібну одиницю, вона повинна перевести заданий обʼєм у потрібну одиницю.
KitchenCalculator.convert({:teaspoon, 9.0}, :tablespoon)
# => {:tablespoon, 3.0}
Зареєструйтеся на Exercism, щоб вивчати й опановувати Elixir, а також 58 концепцій168 вправ та справжнє наставництво від людей, і все це безкоштовно.