2

l want to create new list by giving format,

for example, l have list following:

[ ['Test1',['US','France']],  ['Test2',['German','China','UK']]  ]

now, I want to get result following:

[['Test1','US'],['Test1','France'], ['Test2','German'], ['Test2','China']], ['Test2','UK']]

Thanks

:)

funlive
  • 61
  • 3
  • 10

3 Answers3

2

Straight and simple with !

to_pairs([])         --> [].
to_pairs([X-Ys|XYs]) --> to_pairs_with_key(Ys, X), to_pairs(XYs).

to_pairs_with_key([]    , _) --> [].
to_pairs_with_key([V|Vs], K) --> [K-V], to_pairs_with_key(Vs, K).

Sample query:

?- phrase(to_pairs([test1-[usa,france],test2-[germany,china,uk]]), KVs).
KVs = [test1-usa,test1-france,test2-germany,test2-china,test2-uk].

Note that we represent pairs as (-)/2 compounds, which is a wide-spread "best practice". Switching to this particular representation has many benefits:

  • Interoperability with many other Prolog library predicates
  • Better readability (more concise terms, see example below)
  • Increased efficiency

To work with the representation that you used in the questions, just add two maplist/3 goals:

?- use_module(library(lambda)).
true.

?- Xss0 = [[test1,[usa,france]],
           [test2,[germany,china,uk]]],
   maplist(\[K,Vs]^(K-Vs)^true,Xss0,Xss1),
   phrase(to_pairs(Xss1),Ys0),
   maplist(\ (K-V)^[K,V]^true,Ys0,Ys1).
Xss0 = [[test1,[usa,france]],[test2,[germany,china,uk]]],
Xss1 = [ test1-[usa,france] , test2-[germany,china,uk] ],
Ys0  = [ test1-usa , test1-france , test2-germany , test2-china , test2-uk ],
Ys1  = [[test1,usa],[test1,france],[test2,germany],[test2,china],[test2,uk]].
Community
  • 1
  • 1
repeat
  • 18,496
  • 4
  • 54
  • 166
0

Prolog is quiet far for me, but I think you should do something like:

First([Key,[Head, Tail]], Res):- 

Res will be your final list. If res is empty, then you must create Res = [ Key, Head ]and call Firstwith [Key, [Tail], Res]

Do you see the idea?

Aif
  • 11,015
  • 1
  • 30
  • 44
  • Sorry, l can't see, prolog is different with OOP, l am changing thinking from OOP to Prolog, so l always make mistakes ..... – funlive Apr 10 '11 at 10:41
0

Non-recursive variant:

heads( List, NewList ) :-
    findall( [Name1, Name2],
        (
        member( [Name1, Y], List),
        member( Name2, Y)
        ),
        NewList).

So we have that:

?- heads([['Test1',['US','France']],['Test2',['German','China']]], X).
X = [['Test1', 'US'], ['Test1', 'France'], ['Test2', 'German'], ['Test2', 'China']].

Or, we can make some recursive predicate (it's available only for lists with 2 country-names (for example ['US','France'])):

pooq( [], [] ).
pooq( [[Name1, [Govno, Blevota]] | Tail], List ) :-
    append( [[Name1, Govno],[Name1,Blevota]], ListNew, List ),
    pooq( Tail, ListNew ).

And have smth like that:

?- pooq([['Test1',['US','France']],['Test2',['German','China']]], X).
X = [['Test1', 'US'], ['Test1', 'France'], ['Test2', 'German'], ['Test2', 'China']].

Enjoy

  • thanks very much, i use foreach & append for realizing this function, this is thinking OOP, but it doesn't work, your method is good for studing thinking Prolog :) – funlive Apr 10 '11 at 11:20