Prolog list to line separated by commas

I have a list like [apple, orange] and I want to convert it to a string like "apple,orange" in Prolog. Do you have any ideas?

+4
source share
6 answers

In SWI-Prolog, you can simply use atomic_list_concat/3 and atom_string/2 :

 ?- atomic_list_concat([apple, banana, oranges], ',', Atom), atom_string(Atom, String). Atom = 'apple,banana,oranges', String = "apple,banana,oranges". 
+5
source

In SWI-Prolog, you can use with_output_to/2 . Below are two versions, one of which is used by write/1 , and the other by writeq/1 . From your question it is not clear what behavior you require.

 ?- List = [apple, 'ora\\nge'], with_output_to(codes(Codes), write(List)), format("~s", [Codes]). [apple,ora\nge] List = [apple, 'ora\\nge'], Codes = [91, 97, 112, 112, 108, 101, 44, 111, 114|...]. ?- List = [apple, 'ora\\nge'], with_output_to(codes(Codes), writeq(List)), format("~s", [Codes]). [apple,'ora\\nge'] List = [apple, 'ora\\nge'], Codes = [91, 97, 112, 112, 108, 101, 44, 39, 111|...]. 
+4
source

if you use swi-prolog you can also do the following:

1) use string_to_list / 2 (you can give a list and get a string or give a string and get a list). the problem is that it does not insert commas, so you will have to insert commas between the items in your list manually; sort of

 insert_commas([],[]). insert_commas([H|T],[H,', '|TC]):- insert_commas(T,TC). 

so your predicate will be something like this:

 list_string_with_commas(L,S):- insert_commas(L,LC), string_to_list(S,LC). 

2) you can use swritef / 3 and string_concat / 3. swritef / 3 works like writef / 2, but instead of writing to the output, it creates a data line.

 list_string_with_commas([],""). list_string_with_commas([H,T],S):- swritef(SH,"%t, ",[H]), list_string_with_commas(T,ST), string_concat(SH,ST,T). 

you might want to optimize tail recursion

+1
source

I'm new to Prolog, but this is what I came up with.

 list_codes([], ""). list_codes([Atom], Codes) :- atom_codes(Atom, Codes). list_codes([Atom|ListTail], Codes) :- atom_codes(Atom, AtomCodes), append(AtomCodes, ",", AtomCodesWithComma), append(AtomCodesWithComma, ListTailCodes, Codes), list_codes(ListTail, ListTailCodes). list_string(List, String) :- ground(List), list_codes(List, Codes), atom_codes(String, Codes). list_string(List, String) :- ground(String), atom_codes(String, Codes), list_codes(List, Codes). 

which gives:

 ?- list_string([], S). S = '' . ?- list_string([apple], S). S = apple . ?- list_string([apple, orange], S). S = 'apple,orange' . ?- list_string([apple, orange, peach], S). S = 'apple,orange,peach' . 

and:

 ?- list_string(L, ''). L = [] . ?- list_string(L, 'banana'). L = [banana] . ?- list_string(L, 'banana,litchi'). L = ['banana,litchi'] . 
0
source

Sorry, I do not have enough comments to add this comment to the Gavin Lock answer. Gavin's solution is good as long as it goes, but it needs to be tuned to avoid duplicate answers (or rather variations on the same answer). The problem is that a single atom list is combined into two sentences in list_codes / 2: the second And the third sentence. (A list with one element still has a tail, i.e. an empty list.) I believe that only the binding of the second sentence is required. The third sentence is apparently intended to be recursive for lists that still contain at least two elements. Therefore, I recommend amending this sentence as follows:

 list_codes([Atom,Next|ListTail], Codes) :- atom_codes(Atom, AtomCodes), list_codes([Next|ListTail], ListTailCodes), append(AtomCodes, ",", AtomCodesWithComma), append(AtomCodesWithComma, ListTailCodes, Codes). 

This will only be combined if the list contains at least two elements and does not allow two solutions to be obtained.

0
source

term_string (30 min SO characters)

-1
source

All Articles