Get elements from list of lists

后端 未结 2 1995
生来不讨喜
生来不讨喜 2020-12-02 01:13

is it possible to get all elements from list of lists in Prolog?

Something like: We have getElements([[[a,b,[c]],d,e],f,g,[h,[i,j]]],S) and the result is: S = [a,b,

相关标签:
2条回答
  • 2020-12-02 01:33

    You asked for all elements of a list of lists. That is, for [[1,2,3],[4]] this would be the list [1,2,3,4]. However, for [[[1],[3]]] this would be the list [[1],[3]] since [1] and [3] are elements. For this reason, flatten/2 is incorrect it gives you [1,3] as an answer. Also, for 1 it gives [1]...

    Here is a solution using dcg:

    seq([]) --> [].
    seq([E|Es]) --> [E], seq(Es).
    
    seqq([]) --> [].
    seqq([Es|Ess]) --> seq(Es), seqq(Ess).
    
    ?- phrase(seqq([[[1],[3]]]), Xs).
    Xs = [[1],[3]].
    
    ?- phrase(seqq(1), Xs).
    false.
    

    This solution now works also for cases like the following:

    ?- phrase(seqq([S1,S2]), [1,2]).
    S1 = [],
    S2 = [1,2] ;
    S1 = [1],
    S2 = [2] ;
    S1 = [1,2],
    S2 = [] ;
    false.
    

    Whereas flatten/2 is completely wrong:

    ?- flatten([S1,S2],[1,2]).
    S1 = 1,
    S2 = 2.
    
    0 讨论(0)
  • 2020-12-02 01:48

    In SWI-Prolog (and maybe others), you can use flatten/2:

    ?- flatten([[[a,b,[c]],d,e],f,g,[h,[i,j]]], S).
    S = [a, b, c, d, e, f, g, h, i|...].
    

    Note that the SWI-Prolog manual page for flatten/2 includes the following statement:

    Ending up needing flatten/3 often indicates, like append/3 for appending two lists, a bad design.

    However, the page doesn't say whether there is another native predicate to replace it.

    I'm sure a better answer will be supplied.

    0 讨论(0)
提交回复
热议问题