#HSLIDE
#HSLIDE
[1, :two, "three", %{four: 4}, 'five', [6, [:seven], "eight"]]#HSLIDE
+-|-+ +-|-+ +-|-+ +-|-+ +-|-+
|1| -->|2| -->|3| -->|4| -->|5| |
+-|-+ +-|-+ +-|-+ +-|-+ +-|-+
#HSLIDE
a = [1, 2, 3] # [1, 2, 3]
b = [0 | a] # [0, 1, 2, 3]
c = [-2, -1 | b] # [-2, -1, 0, 1, 2, 3]
d = [a | b] # [[1, 2, 3], 0, 1, 2, 3]
e = a ++ b # [1, 2, 3, 0, 1, 2, 3]#HSLIDE
[a | b] = [1, 2, 3]
a # 1
b # [2, 3]
[x, y | z] = [4, 5]
x # 4
y # 5
z # []#HSLIDE
[[{x, _} | a] | b] = [[{9, 10} , 2, 3], 0]
x # 9
a # [2, 3]
b # [0]#HSLIDE
#HSLIDE
defmodule ListUtils do
def length([]), do: 0
def length([_head | tail]), do: 1 + length(tail)
end
ListUtils.length(["cat", "dog", "fish", "horse"]) # 4#HSLIDE
ListUtils.length(["cat", "dog", "fish", "horse"])
= 1 + ListUtils.length(["dog", "fish", "horse"])
= 1 + 1 + ListUtils.length(["fish", "horse"])
= 1 + 1 + 1 + ListUtils.length(["horse"])
= 1 + 1 + 1 + 1 + ListUtils.length([])
= 1 + 1 + 1 + 1 + 0
= 4
#HSLIDE
defmodule ListUtils do
def length(list) when is_list(list), do: do_length(list)
defp do_length(list, n \\ 0)
defp do_length([], n), do: n
defp do_length([head | tail], n), do: do_length(tail, n + 1)
end#HSLIDE
defmodule ListUtils do
def reduce(list, func, acc \\ 0)
when is_list(list) and is_function(func) do
do_reduce(list, func, acc)
end
def do_reduce([], _func, acc), do: acc
def do_reduce([head | tail], func, acc) do
do_reduce(tail, func, func.(head, acc))
end
end#HSLIDE
list_length
= &ListUtils.reduce(&1, fn _, acc -> 1 + end, 0)
list_length.(["cat", "dog", "horse"]) # 3#HSLIDE
defmodule ListUtils do
def filter(list, predicate)
when is_list(list) and is_function(predicate) do
do_filter(list, predicate)
end
defp do_filter(list, predicate, result \\ [])
defp do_filter([], _predicate, result), do: result
defp do_filter([head | tail], predicate, result) do
case predicate.(head) do
true -> do_filter(tail, predicate, result ++ [head])
false -> do_filter(tail, predicate, result)
end
end
end#HSLIDE
ListUtils.filter([1,2,3,4,5], &(rem(&1, 2) == 0)) # => [2, 4]#HSLIDE
a = [1,2,3]
b = a ++ [4]vs.
a = [1,2,3]
b = [0 | a]#HSLIDE
defmodule ListUtils do
def reverse(list) when is_list(list) do
do_reverse(list)
end
defp do_reverse(list, result \\ [])
defp do_reverse([], result), do: result
defp do_reverse([head | tail], result) do
do_reverse(tail, [head | result])
end
end#HSLIDE
ListUtils.reverse([1, 2, 3, 4, 5]) # [5, 4, 3, 2, 1]#HSLIDE
defmodule ListUtils do
def filter(list, predicate)
when is_list(list) and is_function(predicate) do
do_filter(list, predicate)
end
defp do_filter(list, predicate, result \\ [])
defp do_filter([], _predicate, result), do: reverse(result)
defp do_filter([head | tail], predicate, result) do
case predicate.(head) do
true -> do_filter(tail, predicate, [head | result])
false -> do_filter(tail, predicate, result)
end
end
end#HSLIDE
ListUtils.filter([1,2,3,4,5], &(rem(&1, 2) == 0)) # [2, 4]#HSLIDE
defmodule ListUtils do
def map(list, func)
when is_list(list) and is_function(func) do
do_map(list, func)
end
def do_map(list, func, result \\ [])
def do_map([], _func, result), do: reverse(result)
def do_map([head | tail], func, result) do
do_map(tail, func, [func.(head) | result])
end
end#HSLIDE
ListUtils.map([1,2,3,4,5], &(&1 * &1)) [1,4,9,16,25]#HSLIDE
- отворете и разгледайте документацията на
Listмодула - внимавайте при конструирането на списъци
- научете какво е опашкова рекурсия
- ако обръщате списък, използвайте
Enum.reverse/1или:list.reverse/1
#HSLIDE
defmodule Enum
@spec reverse(t) :: list
def reverse(enumerable)
def reverse([]), do: []
def reverse([_] = list), do: list
def reverse([item1, item2]), do: [item2, item1]
def reverse([item1, item2 | rest]) do
:lists.reverse(rest, [item2, item1])
end
def reverse(enumerable) do
reduce(enumerable, [], &[&1 | &2])
end
end#HSLIDE
#HSLIDE
#HSLIDE
#HSLIDE
iex> %{}
%{}
iex> %{name: "Пешо"}
%{name: "Пешо"}#HSLIDE
pesho = %{
name: "Пешо",
age: 35,
hobbies: {:drink, :smoke, :xxx, :eurofootball},
job: "шлосер"
}#HSLIDE
iex> pesho[:name]
"Пешо"
iex> pesho.name
"Пешо"
iex> Map.fetch(pesho, :name)
{:ok, "Пешо"}
iex> Map.fetch!(pesho, :name)
"Пешо"
iex> Map.get(pesho, :name)
"Пешо"#HSLIDE
iex> pesho[:full_name]
nil
iex> pesho.full_name
** (KeyError) key :full_name not found
iex> Map.fetch(pesho, :full_name)
:error
iex> Map.fetch!(pesho, :full_name)
** (KeyError) key :full_name not found#HSLIDE
iex> Map.get(pesho, :full_name)
nil
iex> Map.get(pesho, :full_name, "Петър Петров")
"Петър Петров"
iex> Map.get_lazy(pesho, :full_name, fn -> "Петър Петров" end)
"Петър Петров"#HSLIDE
pesho = %{
"name" => "Пешо",
"age" => 35,
"hobbies" => {:drink, :smoke, :xxx, :eurofootball},
"job" => "шлосер"
}#HSLIDE
iex> pesho["age"]
35
iex> pesho.age
** (KeyError) key :age not found
iex> pesho."age"
** (KeyError) key :age not found#HSLIDE
iex> Map.pop(pesho, :name)
{"Пешо", %{
age: 35,
hobbies: {:drink, :smoke, :xxx, :eurofootball},
job: "шлосер"
}
}
iex> Map.pop(pesho, :full_name, "Петър Панов")
{"Петър Панов", %{...}}
iex> Map.pop_lazy(pesho, :nick, fn -> "PI4A" end)
{"PI4A", %{...}}#HSLIDE
iex> Map.delete(pesho, :name)
%{
age: 35,
hobbies: {:drink, :smoke, :xxx, :eurofootball},
job: "шлосер"
}
iex> Map.delete(pesho, :full_name)
%{
age: 35,
hobbies: {:drink, :smoke, :xxx, :eurofootball},
job: "шлосер",
name: "Пешо"
}#HSLIDE
iex> Map.drop(pesho, [:hobbies, :job])
%{age: 35, name: "Пешо"}#HSLIDE
pesho = %{
name: "Пешо",
age: 35,
hobbies: {:drink, :smoke, :xxx, :eurofootball},
job: "шлосер"
}
iex> %{pesho | hobbies: :none}
%{age: 35, hobbies: :none, job: "шлосер", name: "Пешо"}
iex> %{pesho | drink: :rakia}
** (KeyError) key :drink not found in:
#HSLIDE
iex> Map.merge(pesho, %{hobbies: :just_drinking, drink: :rakia})
%{age: 35, drink: :rakia, hobbies: :just_drinking,
job: "шлосер", name: "Пешо"}#HSLIDE
iex> pesho = %{
age: 35, dring: :rakia, hobbies: :just_drinking, name: "Пешо"
}
%{age: 35, dring: :rakia, hobbies: :just_drinking, name: "Пешо"}
iex> %{name: x} = pesho
%{age: 35, dring: :rakia, hobbies: :just_drinking, name: "Пешо"}
iex> x
"Пешо"#HSLIDE
iex> %{name: _, age: _} = pesho
%{age: 35, dring: :rakia, hobbies: :just_drinking, name: "Пешо"}
iex> %{name: _, age: _, sex: _} = pesho
** (MatchError)#HSLIDE
defmodule A do
def f(%{name: name} = person) do
IO.puts(name)
person
end
end
iex> A.f(pesho)
Пешо
%{age: 35, dring: :rakia, hobbies: :just_drinking, name: "Пешо"}#HSLIDE
data = %{
proboscidea: %{
elephantidae: %{
elephas: [
"Asian Elephant", "Indian Elephant",
"Sri Lankan Elephant"
],
loxodonta: [
"African bush elephant",
"African forest elephant"
]
},
mammutidae: %{ mammut: ["Mastodon"] }
}
}#HSLIDE
iex> put_in(
data, [:proboscidea, :elephantidae, :fictional], ["Jumbo"]
)#HSLIDE
%{
proboscidea: %{
elephantidae: %{
elephas: [
"Asian Elephant", "Indian Elephant",
"Sri Lankan Elephant"
],
fictional: ["Jumbo"],
loxodonta: [
"African bush elephant", "African forest elephant"
]
},
mammutidae: %{ mammut: ["Mastodon"] }
}
}#HSLIDE
iex> put_in(data.proboscidea.elephantidae.fictional, ["Jumbo"])#HSLIDE
iex> get_in(data, [:proboscidea, :elephantidae, :loxodonta])
["African bush elephant", "African forest elephant"]#HSLIDE
- отворете и разгледайте документацията на
Mapмодула - преизползвайте максимална част от вече конструираните Map-ове
- опитвайте се да правите максимално много промени на ведниъж
#HSLIDE
def change_name_and_age(%{name: name, age: age} = person) do
person
|> Map.update(:name, String.capitalize(name))
|> Map.update(:age, age + 1)
enddef change_name_and_age(%{name: name, age: age, email: email}) do
%{name: String.capitalize(name),
age: age + 1,
email: email}
end#HSLIDE
def change_name_and_age(%{name: name, age: age} = person) do
%{person | name: String.capitalize(name), age: age + 1}
end


