Диапазон
Диапазоны представляют собой последовательность нуля, одного или нескольких возрастающих или убывающих целых чисел с общим разностью, называемой шагом.
Диапазоны всегда включают крайние значения и могут иметь пользовательские шаги. Наиболее распространённый способ создания и сопоставления диапазонов — с помощью обозначений first..last и first..last//step, автоматически импортируемых из Kernel:
iex> Enum.to_list(1..3) [1, 2, 3] iex> Enum.to_list(1..3//2) [1, 3] iex> Enum.to_list(3..1//-1) [3, 2, 1]
Диапазоны также могут содержать единственный элемент:
iex> Enum.to_list(1..1) [1] iex> Enum.to_list(1..1//2) [1]
Или даже не содержать элементов вовсе:
iex> Enum.to_list(10..0//1) [] iex> Enum.to_list(0..10//-1) []
При определении диапазона без шага, шаг определяется на основе первого и последнего значения диапазона. Если first >= last, это будет возрастающий диапазон с шагом 1. В противном случае, это убывающий диапазон. Однако неявные убывающие диапазоны устарели. Поэтому, если вам нужен убывающий диапазон от 3 до 1, предпочтительнее использовать 3..1//-1.
Определение
Возрастающий диапазон first..last//step — это диапазон от first до last с шагом step, где step должно быть положительным целым числом, а все значения v должны быть first <= v and v <= last. Таким образом, диапазон 10..0//1 является пустым диапазоном, так как нет значения v, которое бы 10 <= v and v <= 0.
Аналогично, убывающий диапазон first..last//step — это диапазон от first до last с шагом step, где step должно быть отрицательным целым числом, а значения v должны быть first >= v and v >= last. Таким образом, диапазон 0..10//-1 является пустым диапазоном, так как нет значения v, которое бы 0 >= v and v >= 10.
Представление
Внутренне диапазоны представлены как структуры:
iex> range = 1..9//2 1..9//2 iex> first..last//step = range iex> first 1 iex> last 9 iex> step 2 iex> range.step 2
Вы можете напрямую получить доступ к полям диапазона (first, last, и step), но не должны изменять или создавать диапазоны вручную. Вместо этого используйте соответствующие операторы или new/2 и new/3.
Диапазон реализует протокол Enumerable, что означает, что функции в модуле Enum могут быть использованы для работы с диапазонами:
iex> range = 1..10 1..10 iex> Enum.reduce(range, 0, fn i, acc -> i * i + acc end) 385 iex> Enum.count(range) 10 iex> Enum.member?(range, 11) false iex> Enum.member?(range, 8) true
Такие вызовы функций являются эффективными с точки зрения памяти, независимо от размера диапазона. Реализация протокола Enumerable использует логику, основанную только на конечных значениях, и не материализует весь список целых чисел.
Сводка
Типы
Функции
- disjoint?(диапазон1, диапазон2)
Проверяет, являются ли два диапазона непересекающимися.
- new(первое, последнее)
Создаёт новый диапазон.
- new(первое, последнее, шаг)
Создаёт новый диапазон со
step.- size(диапазон)
Возвращает размер
range.
Типы
Функции
disjoint?(диапазон1, диапазон2)Источник
@spec disjoint?(t(), t()) :: boolean()
Проверяет, являются ли два диапазона непересекающимися.
Примеры
iex> Range.disjoint?(1..5, 6..9) true iex> Range.disjoint?(5..1, 6..9) true iex> Range.disjoint?(1..5, 5..9) false iex> Range.disjoint?(1..5, 2..7) false
Шаги также учитываются при вычислении того, являются ли диапазоны непересекающимися:
iex> Range.disjoint?(1..10//2, 2..10//2) true # First element in common in all below is 29 iex> Range.disjoint?(2..100//3, 9..100//5) false iex> Range.disjoint?(101..2//-3, 99..9//-5) false iex> Range.disjoint?(1..100//14, 8..100//21) false iex> Range.disjoint?(57..-1//-14, 8..100//21) false iex> Range.disjoint?(1..100//14, 51..8//-21) false # If 29 is out of range iex> Range.disjoint?(1..28//14, 8..28//21) true iex> Range.disjoint?(2..28//3, 9..28//5) true
new(первое, последнее)Источник
@spec new(limit(), limit()) :: t()
Создаёт новый диапазон.
Если first меньше, чем last, диапазон будет возрастающим от first до last. Если first равно last, диапазон будет содержать один элемент — это число само по себе.
Если first больше, чем last, диапазон будет убывающим от first до last, хотя это поведение устарело. Поэтому рекомендуется явно указывать шаг с помощью new/3.
Примеры
iex> Range.new(-100, 100) -100..100
new(первое, последнее, шаг)Источник
@spec new(limit(), limit(), step()) :: t()
Создаёт новый диапазон со step.
Примеры
iex> Range.new(-100, 100, 2) -100..100//2
size(диапазон)Источник
Возвращает размер range.
Примеры
iex> Range.size(1..10) 10 iex> Range.size(1..10//2) 5 iex> Range.size(1..10//3) 4 iex> Range.size(1..10//-1) 0 iex> Range.size(10..1) 10 iex> Range.size(10..1//-1) 10 iex> Range.size(10..1//-2) 5 iex> Range.size(10..1//-3) 4 iex> Range.size(10..1//1) 0
© 2012 Plataformatec
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.13.4/Range.html