Mix.install([
{:youtube, github: "brooklinjazz/youtube"},
{:hidden_cell, github: "brooklinjazz/hidden_cell"},
{:tested_cell, github: "brooklinjazz/tested_cell"},
{:utils, path: "#{__DIR__}/../utils"}
])
This is a drill exercise:
Drill exercises are meant to provide practise of Elixir's syntax and important language modules so developers can type them out as fast as possible. The problem should not be conceptually difficult to facilitate this goal.
Developers need to commit both Elixir's syntax and core modules/functions to (working) memory so that when writing their code the developer is not slowed down having to remember the syntax or which module function to use. This is analogous to knowing how to spell and the grammar of your (human) language.
To develop familiarity with the Enum module, you will replace
nil
values in a list with values from a second list at the
same index.
For example:
list1 = [0, nil, 2, 3, nil]
list2 = [:a, :b, :c, :d, :e]
ReplaceNils.replace(list1, list2)
[0, :b, 2, 3, :e]
You can assume the lists are of the same length.
Implement the ReplaceNils
module as below:
input1 = [nil, 3, nil, nil, nil, nil, nil, nil, nil, nil]
input2 = [:a, :b, :c, :d, :e, :f, :g, :h, :i, :j]
defmodule ReplaceNils do
# def replace(target_list, source_list) do
# Enum.map(t_elem, fn t_elem -> # this can't work because each of the
# Enum.map(s_elem, fn s_elem -> # first lists elem's iterates over
# case {t_elem, s_elem} do # the entire second list
# {nil, s_elem} -> s_elem # My sense is I can make this work
# {t_elem, s_elem} -> t_elem
# end
# end)
# end)
# end
def replace(target_list, source_list) do
target_list
|> Enum.with_index()
|> Enum.map(fn {t_elem, t_index} ->
if t_elem == nil do
Enum.at(source_list, t_index)
else
t_elem
end
end)
# |> dbg
end
# def replace(target_list, source_list) do
# target_elem_or_source_elem = fn {t_elem, s_elem} -> t_elem || s_elem end
# [target_list, source_list]
# |> Enum.zip()
# |> Enum.map(target_elem_or_source_elem)
# end
end
ReplaceNils.replace(input1, input2)
target_list = [nil, 3, nil, nil, nil, nil, nil, nil, nil, nil]
source_list = [:a, :b, :c, :d, :e, :f, :g, :h, :i, :j]
# Enum.zip([target_list, source_list])
Enum.with_index(target_list)
nil || :a
3 || :b
Here are some additional test data to think about:
Testcase 1:
Input1: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Input2: [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil]
Expected: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Testcase 2:
Input1: [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil]
Input2: [:a, :b, :c, :d, :e, :f, :g, :h, :i, :j]
Expected: [:a, :b, :c, :d, :e, :f, :g, :h, :i, :j]
Testcase 3:
Input1: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Input2: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Testcase 4:
Input1: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Input2: [:a, :b, :c, :d, :e, :f, :g, :h, :i, :j]
Testcase 5:
[1, 2, 3, nil, nil, 6, 7, nil, 9, 10]
[:a, :b, :c, :d, :e, :f, :g, :h, :i, :j]
First Hint
Consider combining at least one of the Enum functions
you have already learned with Enum functions you have
not been exposed to but can find in the Enum
documentation.
Second Hint
Take a look at Enum.with_index. What does it produce
when applied to the target list?
What will use this output to compare and replace
elements from the two lists and output one list?
Here are some example solutions:
Example Solution 1
Enum.at is fine for small lists but has performance
challenges with larger lists.
Can you refactor this code to not use Enum.at?
defmodule ReplaceNils do
def replace(input1, input2) do
input1
|> Enum.with_index()
|> Enum.map(fn {element, index} ->
if element == nil do
Enum.at(input2, index)
else
element
end
end)
end
end
First Hint - Refactor
place hint here
Example Solution 2
defmodule ReplaceNils do
def replace(as, bs) do
a_or_b = fn {a, b} -> a || b end
[as, bs]
|> Enum.zip()
|> Enum.map(a_or_b)
end
end
Possibilities
Here are some other Enum functions to
consider:
Enum.?
Enum.?
Run the following in your command line from the beta_curriculum folder to track and save your progress in a Git commit.
$ git add .
$ git commit -m "finish saferange exercise"
Previous | Next |
---|---|
A Safe Range | Non-Enumerables |