How can we create a nested keyword list from the following list. The list length can change with time.
list
[:a, :b, :c, :d, :e, :f]
how can we convert it to
[a: [b: [c: [d: [e: [f: [ true ] ]]]]]]
Is it possible with elixir as I tried to use recursion but it’s not working as expected.
Thanks
Yes it is possible. It is even the main purpose of functions in FP
… to take something as input, and transform it to any output.
Please show what You have tried.
1 Like
actually, i have tried this
defp identifier_handling([], key_value), do: key_value
defp identifier_handling([{head, []}], key_value), do: key_value
defp identifier_handling(list, key_value) do
[key] =
Keyword.keys(list)
|> IO.inspect()
[head | tail] =
Keyword.values(list)
|> List.flatten()
|> IO.inspect()
identifier_handling([{head, tail}], key_value ++ [{key, head}])
end
and gives me
[a: :b, b: :c, c: :d, d: :e, e: :f]
which is off course not a nested one
Thanks
When You have an Enumerable, and want to get one value… the usual suspect is Enum.reduce.
iex> l = [:a, :b, :c, :d, :e, :f]
iex> Enum.reduce l, [], fn x, acc -> Keyword.put([], x, acc) end
# or
iex> Enum.reduce l, [], fn x, acc -> Keyword.new([{x, acc}]) end
[f: [e: [d: [c: [b: [a: []]]]]]]
This code does not solve your problem, but shows how to nest… I would reverse the list first, and add the final true to get it work.
2 Likes
That makes sense now, so whenever one value is related to the other one, I should use Enum.reduce.
How would to put the true in the final list, do I have to loop through the final list and then put the final value?
iex> l |> Enum.reverse() |> Enum.reduce([true], fn x, acc -> Keyword.new([{x, acc}]) end)
[a: [b: [c: [d: [e: [f: [true]]]]]]]
# or the short version...
iex> l |> Enum.reverse() |> Enum.reduce([true], &Keyword.new([{&1, &2}]))
4 Likes
Enum.reduce is extremely powerful and it has reduced the code to just one line.
2 Likes
Here’s my take:
iex> [:a, :b, :c, :d, :e, :f] |> Enum.reverse() |> Enum.reduce([true], &([{&1, &2}]))
[a: [b: [c: [d: [e: [f: [true]]]]]]]
1 Like
Yes, keyword new is not required 
BTW parens are not required too…
iex> [:a, :b, :c, :d, :e, :f] |> Enum.reverse() |> Enum.reduce([true], &[{&1, &2}])
2 Likes
Perhaps a bit
ish, but I’ve never actually used foldr
before, so I put this together 
iex(40)> :lists.foldr(&[{&1, &2}], [true], [:a, :b, :c, :d, :e, :f])
[a: [b: [c: [d: [e: [f: [true]]]]]]]
4 Likes
You have List.foldr/3
if you want to make it more Elixirish.
3 Likes
xhh
12
If you want to use recursion, it should be as simple as:
defmodule Solution do
def run([]), do: [true]
def run([head | tail]), do: [{head, run(tail)}]
end
Solution.run([:a, :b, :c, :d, :e, :f])
# [a: [b: [c: [d: [e: [f: [true]]]]]]]
2 Likes