For example I have A = [a,b,c,d]
and B = [[q,w,e],[r,t],[y,u],[i,o]]
and I want to create pairs like that C = [[a,[q,w,e]],[b,[r,t]],[c,[y,u]],[d,[i,o]]].
I can create list of pairs, but I don't want to combine everyone with each other. Is there a easy way to do that? I just can't properly define the problem to Google.
3 Answers
This problem does not seem to make much sense to me, but let's try it:
My first observation is that all three lists are of same length. And that effectively you have here an element-wise mapping like so:
a_b_c(A,B,[A,B]).
Now use maplist/4:
?- As = [a,b,c,d], Bs = [[q,w,e],[r,t],[y,u],[i,o]], maplist(a_b_c, As, Bs, Cs).
As = [a,b,c,d], Bs = [[q,w,e],[r,t],[y,u],[i,o]],
Cs = [[a,[q,w,e]],[b,[r,t]],[c,[y,u]],[d,[i,o]]].
However, dare I say, I really would consider rather pairs! I cannot see any merit in above representation whatsoever.
key_value_pair(K,V,K-V).
?- As = [a,b,c,d], Bs = [[q,w,e],[r,t],[y,u],[i,o]], maplist(a_b_c, As, Bs, Cs).
As = [a,b,c,d], Bs = [[q,w,e],[r,t],[y,u],[i,o]],
Cs = [a-[q,w,e],b-[r,t],c-[y,u],d-[i,o]].
maplist/4
is a common predefined or library predicate. See also this post. In case you do not have it:
maplist(_C_3, [], [], []).
maplist(Cont_3, [A|As], [B|Bs], [C|Cs]) :-
call(Cont_3, A, B, C),
maplist(Cont_3, As, Bs, Cs).

- 10,264
- 13
- 101
- 209
I defined the following predicate to solve that task.
merge([X], [Y], [[X,Y]]).
merge([X|L1], [Y|L2], [[X,Y]|L3]):-merge(L1, L2, L3).
The first line is a fact. The result of merging two list with one element each one is the list that only have one element which is a list with two elements X and Y.
The second line states that: the result of merging two lists having at least two elements is a list with the first element equal to a list of two elements (the first element of each list) and the remainder is the result of merging the remainder of the first two lists.
EDIT:
If you want to handle the case of empty lists then you can use this definition:
merge([X], [Y], [[X,Y]]):-!.
merge([], [], []).
merge([X|L1], [Y|L2], [[X,Y]|L3]):-merge(L1, L2, L3).
It is a bit more complex because it uses the cut !
predicate to stop looking for solutions.

- 2,337
- 1
- 25
- 43
-
2`merge([], [], []).` fails? – false May 30 '14 at 17:32
-
@false you are right. I decided to skip corners cases because the question does not specify that case. – rareyesdev May 30 '14 at 17:34
Try something like this:
zip( [] , [Y|Ys , [ nil:Y | Zs ] ) :- % for lists of unequal length,
zip( [] , Ys , Zs ) . % create unmatched pairs and recurse down
zip( [X|Xs] , [] , [ X:nil | Zs ] ) :- % for lists of unqual lengths,
zip( Xs , [] , Zs ) . % create unmatched paris and recurs down
zip( [X|Xs] , [Y|Ys] , [ X:Y | Zs ] ) :- % otherwise
zip( Xs , Ys , Zs ) % - pair up and recurse down.
. %
Other strategies for dealing with source lists of unqual length:
- fail
- discard the excess

- 71,308
- 16
- 93
- 135
-
2This program no longer handles `nil` correctly. Its representation is called **defaulty**. – false May 30 '14 at 20:22