Skip to content

Commit 20ffdef

Browse files
committed
Add support for shuffling
1 parent 4d965b1 commit 20ffdef

File tree

2 files changed

+50
-9
lines changed

2 files changed

+50
-9
lines changed

README.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,25 @@ iex> RandomStringGenerator.generate("ll-")
6767
**Scape**
6868

6969
In order to generate a string containing the characters `l`,`L`,`d` and `p`
70-
as a delimiter you need to use the backslash twice in order to scape it.
70+
as a delimiter, you need to use the backslash twice in order to scape it.
7171

7272
##### Generate a string containing 2 digits followed by the letters `lLdp`.
7373
```elixir
7474
iex> RandomStringGenerator.generate("dd\\l\\L\\d\\p")
7575
"39lLdp"
7676
```
7777

78+
**Shuffling**
79+
80+
I order to generate a string based on a given patter `Lldd` where those
81+
characters are placed in a random order, the `shuffle/1` function should
82+
be used.
83+
84+
##### Generate a string containing 2 lower case letters, 2 digits in random order.
85+
```elixir
86+
iex> RandomStringGenerator.generate("Lldd") |> RandomStringGenerator.shuffle()
87+
"s22E"
88+
```
89+
7890
Full documentation at [https://hexdocs.pm/random_string_generator](https://hexdocs.pm/random_string_generator).
7991

lib/random_string_generator.ex

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,16 @@ defmodule RandomStringGenerator do
4040
RandomStringGenerator.generate("dd\\\\l\\\\L\\\\d\\\\p")
4141
4242
"""
43+
@lower_letter "l"
44+
@upper_letter "L"
45+
@digit "d"
46+
@punctuation "p"
47+
@scape "\\"
4348

4449
@lower_alpha_chars ~w(a b c d e f g h i j k l m n o p q r s t u v w x y z)
4550
@upper_alpha_chars ~w(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z)
4651
@digits ~w(0 1 2 3 4 5 6 7 8 9)
47-
@punctuation [
52+
@punctuations [
4853
"!",
4954
"\"",
5055
"#",
@@ -79,6 +84,8 @@ defmodule RandomStringGenerator do
7984
"~"
8085
]
8186

87+
88+
8289
@doc """
8390
Given a `pattern` string, returns a random generated string.
8491
@@ -90,33 +97,55 @@ defmodule RandomStringGenerator do
9097
9198
"""
9299
@spec generate(String.t()) :: String.t()
93-
def generate(pattern) do
100+
def generate(pattern) when is_binary(pattern) do
94101
generate(pattern, "")
95102
end
96103

104+
@doc """
105+
Given a `pattern` string it shuffles it to a random order, so that it can be
106+
used for the case where the string must contain certain characters but must
107+
be generated in random order.
108+
109+
## Examples
110+
111+
iex> pattern = "lLdp-"
112+
iex> shuffled_pattern = RandomStringGenerator.shuffle(pattern)
113+
iex> String.graphemes(pattern) |> Enum.sort ==
114+
iex> String.graphemes(shuffled_pattern) |> Enum.sort
115+
true
116+
117+
"""
118+
@spec shuffle(String.t()) :: String.t()
119+
def shuffle(pattern) when is_binary(pattern) do
120+
pattern
121+
|> String.graphemes()
122+
|> Enum.shuffle()
123+
|> Enum.join()
124+
end
125+
97126
@spec generate(String.t(), String.t()) :: String.t()
98127
defp generate("", generated_string) do
99128
generated_string
100129
end
101130

102131
# TODO Dry Enum.random
103-
defp generate("l" <> rest, generated_string) do
132+
defp generate(@lower_letter <> rest, generated_string) do
104133
generate(rest, generated_string <> Enum.random(@lower_alpha_chars))
105134
end
106135

107-
defp generate("L" <> rest, generated_string) do
136+
defp generate(@upper_letter <> rest, generated_string) do
108137
generate(rest, generated_string <> Enum.random(@upper_alpha_chars))
109138
end
110139

111-
defp generate("d" <> rest, generated_string) do
140+
defp generate(@digit <> rest, generated_string) do
112141
generate(rest, generated_string <> Enum.random(@digits))
113142
end
114143

115-
defp generate("p" <> rest, generated_string) do
116-
generate(rest, generated_string <> Enum.random(@punctuation))
144+
defp generate(@punctuation <> rest, generated_string) do
145+
generate(rest, generated_string <> Enum.random(@punctuations))
117146
end
118147

119-
defp generate("\\" <> <<pattern::binary-size(1)>> <> rest, generated_string) do
148+
defp generate(@scape <> <<pattern::binary-size(1)>> <> rest, generated_string) do
120149
generate(rest, generated_string <> pattern)
121150
end
122151

0 commit comments

Comments
 (0)