Skip to content

Commit

Permalink
feat(util): add uniquify/1 helper function
Browse files Browse the repository at this point in the history
Adds a helper function that differentiates a list of strings

Relates to elixirs#479
  • Loading branch information
Dimitris Vogiatzidakis committed Oct 19, 2022
1 parent 28125ad commit 55eb688
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 0 deletions.
36 changes: 36 additions & 0 deletions lib/faker/util.ex
Original file line number Diff line number Diff line change
Expand Up @@ -272,4 +272,40 @@ defmodule Faker.Util do
_ -> raise "Rule #{rule_key} not found or not a function"
end
end

@doc """
Uniquify a list of strings adding an index to each subsequent duplicate.
## Examples
iex> Faker.Util.uniquify(["a", "b", "b", "b", "c", "d", "d", "b"])
["a", "b", "b2", "b3", "c", "d", "d2", "b4"]
"""
@spec uniquify(list) :: list
def uniquify(enumerable) when is_list(enumerable) do
uniq_list(enumerable, %{})
end

def uniquify(enumerable) do
raise("Expected a list of strings, received #{inspect(enumerable)}")
end

defp uniq_list([head | _tail] = list, _set) when not is_binary(head) do
raise("Expected a list of strings, received #{inspect(list)}")
end

defp uniq_list([head | tail], set) do
value = head

case set do
%{^value => count} ->
uniq_list(["#{value}#{count + 1}" | tail], Map.put(set, value, count + 1))

%{} ->
[head | uniq_list(tail, Map.put(set, value, 1))]
end
end

defp uniq_list([], _set), do: []
end
22 changes: 22 additions & 0 deletions test/faker/util_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,26 @@ defmodule Faker.UtilTest do
assert Enum.sort(generated_value) == list
end)
end

describe "uniquify/1" do
test "list of strings is properly uniquified" do
assert uniquify(["a", "b", "b", "c"]) == ["a", "b", "b2", "c"]
end

test "list of integers raises an error" do
enumerable = [1, 2, 3, 4]

assert_raise RuntimeError,
"Expected a list of strings, received #{inspect(enumerable)}",
fn -> uniquify(enumerable) end
end

test "non-list as input raises an error" do
enumerable = %{invalid: "map"}

assert_raise RuntimeError,
"Expected a list of strings, received #{inspect(enumerable)}",
fn -> uniquify(enumerable) end
end
end
end

0 comments on commit 55eb688

Please sign in to comment.