Skip to content

Instantly share code, notes, and snippets.

@notriddle
Created February 17, 2017 18:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save notriddle/2f6ccb656aaca88b086beb415014e942 to your computer and use it in GitHub Desktop.
Save notriddle/2f6ccb656aaca88b086beb415014e942 to your computer and use it in GitHub Desktop.
Implement :lists.prefix for any enumerable, in Elixir
defmodule Enum2 do
@type t :: Enum.t
@doc """
If `enum` starts with `prefix`, return true. Otherwise, return false.
### Examples
iex> Enum.starts_with?([1, 2, 3], [1, 2])
true
iex> Enum.starts_with?([:alpha], [])
true
iex> Enum.starts_with?([], [:alpha])
false
"""
@spec starts_with?(t, list) :: boolean
def starts_with?(_, []), do: true
def starts_with?(enum, prefix) do
Stream.zip(enum, prefix)
|> all_equals?(prefix)
end
# Check if all the pairs are equal to each other and to the given list.
#
# iex> all_equals?([{:a, :a}, {:b, :b}], [:a, :b])
# true
# iex> all_equals?([{:a, :a}, {:b, :b}], [:a, :b, :c])
# false
# iex> all_equals?([{:a, :b}, {:c, :c}], [:a, :c])
# false
# iex> all_equals?([{:a, :a}, {:b, :b}, {:c, :c}], [:a, :b])
# false
defp all_equals?(pairs, list) do
pairs
|> Enumerable.reduce({:cont, list}, fn
{a, a}, [a | t] -> {:cont, t}
_, _ -> {:halt, :error}
end)
|> case do
{:done, []} -> true
_ -> false
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment