greenapple

greenapple

Recursive concatenation

Hi,
I’m a beginner, and I’m trying to solve a rather simple question but I’m kinda stuck. I’m trying to write a fully-recursive function that appends a list to the other one, and I’m also not allowed to use any pre-written functions (like Enum.concat or ++ ). I’m honestly not even sure where I would start. I imagine there would be some pattern matching involved and maybe a base case with just one element in each list but I’m not sure. Can somebody help me with this please?

Marked As Solved

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

Right perfect. And if you wanted to do a concat on a list that just took one item, you could do:

def concat([item], list) do
  [item | list]
end

concat([1], [2,3] #=> [1,2,3]

The trick then is to just apply this logic recursively. When doing recursive logic, it’s always a good idea to identify the “base case” which you can think of as “when do I stop recursing?”. In the case of this kind of concat function, you stop recursing when you have just 1 item in the list, because at that point you do a simple prepend.

When you have more than one item, you need to recursively prepend until you hit the base case:

def concat([], list), do: list

def concat([item], list) do
  [item | list]
end

def concat([item | rest], list) do
  [item | concat(rest, list)]
end

The first part of [item | concat(rest, list)] is [item | which you’re already familiar with, that’s setting up item to be prepended to whatever is on the right hand side of |. But this time, instead of prepending it to | list] we do | concat(rest, list)] because we want the item to come before the result of prepending all of the other items.

Also Liked

greenapple

greenapple

I think I understand the solution. Thank you so much for the great explanation, it is very much appreciated!

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

Great!

So let’s start with something very basic: How would you do this simpler function:

prepend(1, [2,3]) #=> [1,2,3]
NobbZ

NobbZ

I think you are missing an edge case here: concat([], [1,2,3])

Last Post!

Aetherus

Aetherus

I believe if you’re trying to find a more ubiquitous solution, implementing reduce/3 and optionally reduce/2 first should always be the way to go because all list operations can be implemented using reduce, including reduce itself.

@type item :: any
@type acc :: any

@spec reduce([item], acc, (item, acc -> acc)) :: acc
def reduce([], acc, _fun) do
  acc
end

def reduce([item | rest], acc, fun) do
  reduce(rest, fun.(item, acc), fun)
end

Then you can implement reverse using reduce.

@spec reverse([item]) :: [item]
def reverse(list) do
  reduce(list, [], fn item, acc -> [item | acc] end)
end

And finally, you have enough tools to implement concat.

@spec concat([item], [item]) :: [item]
def concat(list1, list2) do
  list1
  |> reverse()
  |> reduce(list2, fn item, acc -> [item | acc] end)
end

See? Down the rabbit hole, it’s just about recursion.

Where Next?

Popular in Questions Top

lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New

Other popular topics Top

JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 31525 112
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New

We're in Beta

About us Mission Statement