Skip to content

Instantly share code, notes, and snippets.

@rrichardsonv
Created January 30, 2020 19:43
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 rrichardsonv/079b42c60b766cd8949ed0d3d79a80dd to your computer and use it in GitHub Desktop.
Save rrichardsonv/079b42c60b766cd8949ed0d3d79a80dd to your computer and use it in GitHub Desktop.
defmodule GoIntumerables do
@doc """
## Example
take_into(%Bar{id: 1}, [:id], [])
# => [id: 1]
opts = [open: true, secret: "foo", source_id: "2"]
opts
|> take_into([:open, :source_id], %{}, fn {k, v} -> {to_string(k), v} end)
|> URI.encode_query()
# => "?open=true&source_id=2"
"""
def take_into(source_enum, keys, result, transform \\ & &1)
when is_enum(source_enum) and is_enum(result) and is_function(transform, 1),
do: for item <- source_enum, should_take?(item, keys), into: result, do: item |> as_pair() |> transform.()
defguardp is_enum(maybe_enum) when is_list(maybe_enum) or is_map(maybe_enum)
defp should_take?({k, _}, keys), do: k in keys
defp should_take?(item, keys) when not is_tuple(item), do: item in keys
defp as_pair({_, _} = pair), do: pair
defp as_pair(item) when not is_tuple(item), do: {item, true}
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment