0

I know that to extract the third element from a simple list containing four elements such as [1,2,3,4] I would do so as below.

third([_,_,E,_], E).

I would like to extract the third element from a group of nested lists. For example if I had [[1,2,3,4],[5,6,7,8],[9,10,11,12]], I would want an output of [3,7,11].

Any help would be much appreciated.

repeat
  • 18,496
  • 4
  • 54
  • 166

3 Answers3

2

Use the widely available maplist/3 like in the following sample query:

?- maplist(third, [[1,2,3,4],[5,6,7,8],[9,10,11,12]], Xs).
Xs = [3, 7, 11].
Community
  • 1
  • 1
repeat
  • 18,496
  • 4
  • 54
  • 166
0

My guess:

third([], []) :- !.
third([[_, _, E|_]|Rest], [E|R]) :- third(Rest, R).

I know some people dislike cut (!), but it sounds enough to me.


[update 2016-03-14]

A robuster version:

third([], []).
third([Xs|Rest], R) :-
    length(Xs, Len),
    (Len < 3 -> third(Rest, R);
                (Xs = [_, _, E|_],
                 R = [E|R1],
                 third(Rest, R1))).

[/update]

0

certainly, the solution of @repeat (maplist predicat) is the elegant answer however, this is a simplest answer :

version 1 :

third_([], []).
third_([List|Rest], [R|Res]) :-
        third(List, R),
        third_(Rest, Res).

version 2

third_([], []).
third_([[_,_,R,_]|Rest], [R|Res]) :-
        third_(Rest, Res).

test :

| ?- third_(Xs,Res).
Xs = [],
Res = [] ? ;
Xs = [[_A,_B,_C,_D]],
Res = [_C] ? ;
Xs = [[_A,_B,_C,_D],[_E,_F,_G,_H]],
Res = [_C,_G] ? ;
Xs = [[_A,_B,_C,_D],[_E,_F,_G,_H],[_I,_J,_K,_L]],
Res = [_C,_G,_K] ? 
Ans Piter
  • 573
  • 1
  • 5
  • 17