Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check index in an Erlang list?

Tags:

erlang

How I would like to make a new list which is originated from two different lists, so I make the below code, but it gives the unexpected result.

I am not sure why it happens. I would like to understand why this happens.

What I expect.

ListA = [1,2,3],

ListB = [a,b,c],

ListC = [{1,a}, {2,b}, {3,c}].

What I get.

ListC = [{1,a},{1,b},{1,c},{2,a},{2,b},{2,c},{3,a},{3,b},{3,c}]

ListA = [1,2,3],
ListB = [a,b,c],
LictC = [{A, B} || A<-ListA, B<-ListB]

Maybe..

ListA = [1,2,3],
ListB = [a,b,c],
LictC = [{A, B} || A<-ListA, B<-ListB, Condition]

If there is a function that to check the order of the array, it can be the condition. In detail, if the element of ListA has same index with the element of ListB, the condition function returns true.

like image 783
Ray Avatar asked Dec 05 '25 16:12

Ray


1 Answers

In Real

ListC = [{1,a},{1,b},{1,c},{2,a},{2,b},{2,c},{3,a},{3,b},{3,c}]

ListA = [1,2,3],
ListB = [a,b,c],
LictC = [{A, B} || A<-ListA, B<-ListB]

I am not sure why it happens

Because that is the way list comprehensions are defined to work. A list comprehension with two generators works exactly the same way as two nested for loops in other languages:

#python

listA = [1,2,3]
listB = ["a", "b", "c"]
results = []

for a in listA:
    for b in listB:
        results.append((a,b))

print(results)

output:

[(1, 'a'), (1, 'b'), (1, 'c'), (2, 'a'), (2, 'b'), (2, 'c'), 
 (3, 'a'), (3, 'b'), (3, 'c')]

You take the first element of ListA, and you combine it with every element of ListB; then you take the second element of ListA, and you combine it with every element of ListB; etc.

how can I fix this

"When you've got a hammer (list comprehensions) everything looks like a nail." In this case, you've got the wrong tool for the job. Instead, you should use lists:zip/2 to get the result you want:

1> ListA = [1,2,3].
[1,2,3]

2> ListB = [a,b,c].
[a,b,c]

3> lists:zip(ListA, ListB).
[{1,a},{2,b},{3,c}]

Or, you can define your own recursive function to do what you want:

-module(a).
-compile(export_all).

combine([], []) -> [];
combine([H1|T1], [H2|T2]) ->
    [{H1,H2} | combine(T1, T2)].

In the shell:

~/erlang_programs$ erl
Erlang/OTP 20 [erts-9.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V9.3  (abort with ^G)

1> c(a).                      
a.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,a}

2> a:combine([1,2,3], [a,b,c]).
[{1,a},{2,b},{3,c}]

3> 

if the element of ListA has same index with the element of ListB

In erlang, the elements of a list do not have index positions. Erlang lists are not the same as python lists or arrays in C/C++. Rather erlang lists are implemented as linked lists, whose elements can be sequentially accessed but not randomly accessed.

like image 197
7stud Avatar answered Dec 07 '25 17:12

7stud



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!