Ruby has a great method for enumerations called #each_with_index. It’s a handy way to iterate over a list of elements and and know where you’re at while doing it.
Erlang has a group of highly optimized list operations in the lists module (Try erl -man lists to see them all). We’re going to be using those to build our Erlang version of #each_with_index.
There are two methods from list we’re going to use: lists:seq and lists:zip. lists:seq simply returns a list of integers between a given range. For instance:
1> Seq = lists:seq(0, 9). [0,1,2,3,4,5,6,7,8,9]
lists:zip takes two lists (of equal length) and returns a list of tuples. Like so:
2> lists:zip([a,b,c], [1,2,3]). [{a,1},{b,2},{c,3}]
The last thing we need is a list comprehension, which is similar to each with a block in Ruby. For instance, in Ruby:
>> [:a, :b, :c].each { |element| puts element } a b c => [:a, :b, :c]
In Erlang we would do the following:
3> [io:format("~p~n", [Element]) || Element <- [a,b,c]]. a b c [ok,ok,ok]
There is one difference here: the Erlang list comprehension returns a new list which is the value of each call to io:format. In this way an Erlang list comprehension is closer to Ruby’s #collect rather than #each.
We now have all the pieces to build our Erlang version of #each_with_index.
4> EachWithIndex = fun(L, X) -> [ X(Element, Index) || {Element, Index} <- lists:zip(L, lists:seq(1, length(L))) ] end.
Whats going on here?
lists:zip(L, lists:seq(1, length(L)))
creates a list of tuples with each tuple containing an element of L and a companion integer.
[X(Element, Index) || {Element, Index} <- lists:zip(L, lists:seq(1, length(L)))]
tells us to take that list of tuples and do a list comprehension on each of the elements, calling fun X in turn.
EachWithIndex = fun(L, X) -> ... end.
creates a fun (think lambda) and assigns it to EachWithIndex. You could just as easily create this as a regular function in a .erl file somewhere.
Now we can call our new EachWithIndex function by passing in a list and a fun:
5> EachWithIndex([a,b,c,d,e], fun(Element, Index) -> io:format("~p at ~p~n", [Element, Index]) end). a at 1 b at 2 c at 3 d at 4 e at 5 [ok,ok,ok,ok,ok]

2 Comments
In all list comprehensions you forgot to put ||
Re: Ivan. Interesting, they are being converted by something to in the markup. I’ll look into this and fix it.