How to replace elements in an array in elixir

Viewed 3702

I want to replace all occurrences of 2 with 3.I want to do this without using the value of the index because that would be hardcoding. What I have so far is:


list=[1,2,3,4,2,34,2]

replace_at(list, index, value)

Enum.each list, fn(x) ->
if x==2 do
  replace_at(list, index, 3)
end

Enum.each list, fn(x) ->
IO.puts x
end

3 Answers

In Elixir, you do not have arrays, but linked list. If you simply want to replace all ocurrences of 2 with 3, you can use the map function, of the Enum module like this:

iex(1)> Enum.map(list, fn x -> if x == 2, do: 3, else: x end)
[1, 3, 3, 4, 3, 34, 3]

You could also use pattern matching:

iex(1)> Enum.map(list, fn
...(1)> 2 -> 3
...(1)> x -> x
...(1)> end)

It is essential to know that Elixir is immutable, so you cannot replace values in a list; actually, you create a new list.

You can use the map method from Enum module, where you can found a bunch of algorithms to deal with enumerables.

iex(2)> [1, 2, 3, 4, 2, 34, 2] |> Enum.map(fn
...(2)>   2 -> 3
...(2)>   other -> other
...(2)> end)
[1, 3, 3, 4, 3, 34, 3]

A method with this implementation could be like the code below:

defmodule Replace do

  def replace_all(list, from, to) do
    list
    |> Enum.map(fn
      ^from -> to
      other -> other
    end)
  end

end

We don’t have arrays, and access by index is costly.

If you still want to accomplish it, Enum.with_index/2 is your friend.

replace_at = fn list, index, value -> 
  list
  |> Enum.with_index()
  |> Enum.map(fn
    {_, ^index} -> value # match index
    {value, _} -> value  # anything else   
  end)
end

And use it like

# index      0  1  2  3  4  5   6  
replace_at.([1, 2, 3, 4, 2, 34, 2], 2, 42)
#⇒ [1, 2, 42, 4, 2, 34, 2]

Replacing all 2s has nothing to do with the index, one does not need the index to do it. Just use Enum.map/2 out of the box.


Also, you should learn that Enum.each/2 does not modify anything ever.

Related