2

I'm new to Elixir and trying to solve guitar tab problem. My code:

def sumTabs([head|tail], result) do
        nextLine = hd(tail)
        tail = List.delete(tail, nextLine)
        head
        |> Enum.with_index
        |> Enum.each(fn({x, i}) ->
            s = [x <> Enum.at(nextLine, i) |> to_charlist]
            IO.inspect s
            result = [result | s] 
            IO.inspect result end)
        result
    end

I want to update result, which is an empty list at the start, but in each iteration of Enum.each function, the result is empty. I think it is because of the anonymous function.

For the start I want it to work at least with two lines.

Input:

tab = """
  e|-7-----7-----7-----7-----5-----3-----3-----2-----0-----0-----|
  B|---0-----0-----0-----0-----0-----0-----0-----0-----0-----0---|
  G|-----0-----0-----0-----0-----0-----0-----0-----0-----0-----0-|
  D|-------------------------------------------------------------|
  A|-------------------------------------------------------------|
  E|-------------------------------------------------------------|
  """

Output:

['eB']
[[], 'eB']
['||']
[[], '||']
['--']
[[], '--']
['7-']
[[], '7-']
['--']
[[], '--']
['-0']
[[], '-0']
['--']
[[], '--']
['--']
[[], '--']
['--']
[[], '--']
['7-']
[[], '7-']
['--']
[[], '--']
['-0']
[[], '-0']
['--']
[[], '--']
['--']
[[], '--']
['--']
[[], '--']
['7-']
[[], '7-']
['--']
[[], '--']
['-0']
[[], '-0']
['--']
[[], '--']
['--']
[[], '--']
['--']
[[], '--']
['7-']
[[], '7-']
['--']
[[], '--']
['-0']
[[], '-0']
['--']
[[], '--']
['--']
[[], '--']
['--']
[[], '--']
['5-']
[[], '5-']
['--']
[[], '--']
['-0']
[[], '-0']
['--']
[[], '--']
['--']
[[], '--']
['--']
[[], '--']
['3-']
[[], '3-']
['--']
[[], '--']
['-0']
[[], '-0']
['--']
[[], '--']
['--']
[[], '--']
['--']
[[], '--']
['3-']
[[], '3-']
['--']
[[], '--']
['-0']
[[], '-0']
['--']
[[], '--']
['--']
[[], '--']
['--']
[[], '--']
['2-']
[[], '2-']
['--']
[[], '--']
['-0']
[[], '-0']
['--']
[[], '--']
['--']
[[], '--']
['--']
[[], '--']
['0-']
[[], '0-']
['--']
[[], '--']
['-0']
[[], '-0']
['--']
[[], '--']
['--']
[[], '--']
['--']
[[], '--']
['0-']
[[], '0-']
['--']
[[], '--']
['-0']
[[], '-0']
['--']
[[], '--']
['--']
[[], '--']
['--']
[[], '--']
['||']
[[], '||']

Code before sumTabs function:

defmodule TabPlayer do
    def parse(tab) do
        String.split(tab, "\n") 
            |> Enum.map(fn n -> to_string n end)
            |> List.delete([])
            |> Enum.map(fn n -> String.graphemes n end)
            |> sumTabs([])
            |> IO.inspect
    end

1 Answer 1

4

Variables in Elixir are immutable. You cannot reassign the value inside Enum.each and expect it to change outside. What this code does is create a new result value that lasts until the end of the anonymous function.

You can use Enum.reduce/3 here, returning the new result value on every iteration. Assuming the rest of your logic is correct, here's how the code can be rewritten to use Enum.reduce/3. Note that I'm making use of the fact that IO.inspect prints a value and then returns it. So IO.inspect(x); x is the same as IO.inspect(x).

def sumTabs([head|tail], result) do
  nextLine = hd(tail)
  tail = List.delete(tail, nextLine)
  head
  |> Enum.with_index
  |> Enum.reduce([], fn({x, i}, acc) ->
    s = IO.inspect [x <> Enum.at(nextLine, i) |> to_charlist]
    IO.inspect [s | acc]
  end)
  # We need to reverse at the end since we're creating a reversed list in
  # `Enum.reduce` for efficiency.
  |> Enum.reverse
end
Sign up to request clarification or add additional context in comments.

3 Comments

This works nice, thank you! But how can I get "acc" variable to give it for the next function call or do smth with it later?
You could store the final value like this: result = head |> ... and then use that. Enum.reduce returns the final value of acc. Is that what you meant?
Just a side note, @Dogbert, you can actually get the nextLine variable in the function head like so sumTabs([first, next | tail]) do ... and then you wouldn't have to delete it from the tail. Also, it's bad practice to re-assign variables

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.