diff options
author | Artur Plysyuk <ifuelen@gmail.com> | 2023-02-08 22:18:37 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-02-08 21:18:37 +0100 |
commit | 4a236dc231ad4f4576cb600956f7fec8dd47c257 (patch) | |
tree | fc0863f909a93610e5a4540708b01bdc952ff24e | |
parent | b5d883c8bbd44dcbdee6ca6f8dc5f37acbb899dc (diff) | |
download | elixir-4a236dc231ad4f4576cb600956f7fec8dd47c257.tar.gz |
Optimize Enum.to_list for ranges (#12384)
Closes #12383
-rw-r--r-- | lib/elixir/lib/enum.ex | 1 | ||||
-rw-r--r-- | lib/elixir/lib/range.ex | 20 |
2 files changed, 21 insertions, 0 deletions
diff --git a/lib/elixir/lib/enum.ex b/lib/elixir/lib/enum.ex index bcea77bca..d9bcde75f 100644 --- a/lib/elixir/lib/enum.ex +++ b/lib/elixir/lib/enum.ex @@ -3675,6 +3675,7 @@ defmodule Enum do """ @spec to_list(t) :: [element] def to_list(enumerable) when is_list(enumerable), do: enumerable + def to_list(%{__struct__: Range} = range), do: Range.to_list(range) def to_list(%_{} = enumerable), do: reverse(enumerable) |> :lists.reverse() def to_list(%{} = enumerable), do: Map.to_list(enumerable) def to_list(enumerable), do: reverse(enumerable) |> :lists.reverse() diff --git a/lib/elixir/lib/range.ex b/lib/elixir/lib/range.ex index 23af606af..7bde6701f 100644 --- a/lib/elixir/lib/range.ex +++ b/lib/elixir/lib/range.ex @@ -390,6 +390,26 @@ defmodule Range do end @doc """ + Converts a range to a list. + """ + @doc since: "1.15.0" + def to_list(first..last//step) + when step > 0 and first <= last + when step < 0 and first >= last do + :lists.seq(first, last, step) + end + + def to_list(_first.._last//_step) do + [] + end + + # TODO: Remove me on v2.0 + def to_list(%{__struct__: Range, first: first, last: last}) do + step = if first <= last, do: 1, else: -1 + :lists.seq(first, last, step) + end + + @doc """ Checks if two ranges are disjoint. ## Examples |