So i have been doing a udemy course to learn Elixir, where i am suppose to take list and create new list that contains a lists of values in length of 3
So this is my old list
[23, 137, 4, 86, 54, 223, 37, 191, 22, 167, 25, 238, 102, 56, 39, 4]
and i want to convert it to this
[[23, 137, 4],[ 86, 54, 223],[ 37, 191, 22],[ 167, 25, 238],[ 102, 56, 39]]
My code
def main(name) do
name
|> hash
|> pickColor
|> buildGrid
end
def buildGrid(%Identicon.Image{hex: hex}=image) do
hex
|>Enum.chunk_every(3, :discard)
end
def pickColor(%Identicon.Image{hex: [r,g,b | _tail]} = image) do
%Identicon.Image{image | color: {r,g,b}}
end
def hash(name) do
hex = :crypto.hash(:md5,name)
|> :binary.bin_to_list()
%Identicon.Image{hex: hex}
end
the response im getting is
** (FunctionClauseError) no function clause matching in Enum.chunk_every/4
The following arguments were given to Enum.chunk_every/4:
# 1
[23, 137, 4, 86, 54, 223, 37, 191, 22, 167, 25, 238, 102, 56, 39, 4]
# 2
3
# 3
:discard
# 4
[]
Attempted function clauses (showing 1 out of 1):
def chunk_every(enumerable, count, step, leftover) when is_integer(count) and count > 0 and is_integer(step) and step > 0
(elixir 1.15.0) lib/enum.ex:547: Enum.chunk_every/4
(identicon 0.1.0) lib/identicon.ex:23: Identicon.buildGrid/1
iex:6: (file)
You are doing this:
iex> Enum.chunk_every(list, 3, :discard)
** (FunctionClauseError) no function clause matching in Enum.chunk_every/4
But you need to do this:
iex> Enum.chunk_every(list, 3, 3, :discard)
[[23, 137, 4], [86, 54, 223], [37, 191, 22], [167, 25, 238], [102, 56, 39]]
There are actually three forms of Enum.chunk_every
:
Enum.chunk_every/2
, is a shortcut to the three argument argument form: chunk_every(list, count)
→ chunk_every(list, count, count)
, where the count
is also passed as the third argument, step
.Enum.chunk_every/4
, is actually the four-argument form where the default value of the fourth argument, leftover
, is the empty list: chunk_every(list, count, step)
→ chunk_every(list, count, step, [])
. This differs from the two-argument form, because step
is not optional.leftover
.Your code is doing Enum.chunk_every(enum, 3, :discard)
, attempting to pass :discard
as the fourth leftover
argument, but without passing the required third step
argument. So Elixir is correctly complaining that there is no version of this function that takes (list, integer, atom)
arguments. The fix is to pass the required third argument step
, with the same value as count
.
It's confusing, because the two-argument version allows the step
to default to count
automatically (and by extension, leftover
to default to []
automatically), but the four-argument version requires that you pass step
explicitly, while still allowing the leftover
argument to be optional.