|
View:
New views
3 Messages
—
Rating Filter:
Alert me
|
|
|
Merging Lists and Writing Delimited RecordsAll, In case any of you might find these useful (I have), here
are a couple of predicates that help merge lists of lists and produce delimited
records (to be read by something like Excel). They seem to work fine for my
work, but there may be corner cases where things fall apart. At any rate, have
at it. % The following little predicate will facilitate the merging
of arbitrary number of lists: % heads/3: Given a list of lists LoL, produce a list
consisting only of the heads of the lists in LoL. % As a by product, heads/3 also produces the list % It returns LoH=[] and heads(LoL,LoH,LoT) :- heads(LoL,[],LoH,[],LoT). heads([],LoH,LoH,LoT, heads([[H|Tail]|T],HAcc1,LoH,TAcc1, append(HAcc1,[H],HAcc2), append(TAcc1,[Tail],TAcc2), heads(T,HAcc2,LoH,TAcc2, % writeDelimRecs/3: Assume lists of atoms and write
delimited records to a given stream. % Writes nothing if LoL contains an empty list. writeDelimRecs(_,_,LoL) :- member([],LoL),!. writeDelimRecs(Stream,Delim, LoL) :- heads(LoL,LoH, concat_atom(LoH,Delim,Rec), write(Stream,Rec),
nl(Stream), writeDelimRecs(Stream,Delim, Regards, |
|
|
Re: Merging Lists and Writing Delimited RecordsOn Oct 30, 2009, at 2:42 PM, Carroll, Michael L. wrote: > All, > > In case any of you might find these useful (I have), here are a > couple of predicates that help merge lists of lists and produce > delimited records (to be read by something like Excel). They seem > to work fine for my work, but there may be corner cases where things > fall apart. At any rate, have at it. > > % The following little predicate will facilitate the merging of > arbitrary number of lists: > > % heads/3: Given a list of lists LoL, produce a list consisting > only of the heads of the lists in LoL. > % As a by product, heads/3 also produces the list LoT of > the remaining tails of lists in LoL. > % It returns LoH=[] and LoT=[], when LoL is empty. > > heads(LoL,LoH,LoT) :- heads(LoL,[],LoH,[],LoT). > > heads([],LoH,LoH,LoT,LoT) :- !. > heads([[H|Tail]|T],HAcc1,LoH,TAcc1,LoT) :- > append(HAcc1,[H],HAcc2), > append(TAcc1,[Tail],TAcc2), > heads(T,HAcc2,LoH,TAcc2,LoT). Aside from the rather confusing name and the very strange indentation, this is essentially the ml_taketop/3 predicate from the DEC-10 Prolog library MULTIL.PL, which has been freely available on the web since the early 1980s. %. ml_taketop(?Lists, ?Heads, ?Tails) % is true when Lists is a list of non-empty lists, Heads is a list % whose elements are the heads of the elements of Lists, and Tails % is a list whose elements are the tails of Lists. ml_taketop([], [], []). ml_taketop([[Head|Tail]|Lists], [Head|Heads], [Tail|Tails]) :- ml_taketop(Lists, Heads, Tails). This was a private predicate of the module (note the "." after the first "%", it told the documentation extractor not to extract this comment). The "ml_" prefix is because it comes from DEC-10 Prolog, which didn't have modules. As it wasn't exported, the fact that this name isn't that helpful either didn't matter much. > > % writeDelimRecs/3: Assume lists of atoms and write delimited > records to a given stream. > % Writes nothing if LoL contains an empty list. ThisIsNotJavaSoYouDoNotHaveToWriteNamesThatNoOneCanReadWithoutPain. > > writeDelimRecs(_,_,LoL) :- member([],LoL),!. > writeDelimRecs(Stream,Delim, LoL) :- heads(LoL,LoH,LoT), > > concat_atom(LoH,Delim,Rec), > > write(Stream,Rec), nl(Stream), > > writeDelimRecs(Stream,Delim,LoT). What you have here is not so much a "list of lists", but a TABLE presented as a list of columns, rather than the somewhat easier-to-handle list of rows. The I/O predicates with a Stream argument should never have been invented. Every time you call a built-in predicate with such an argument, it has to check it again and again and again and again. Switch to the new stream, do all the writing you want, switch back, and there are just two checks. with_output_to/2 is an extremely useful command. So use it. write_delimited_records(Stream, Columns, Delimiter) :- with_output_to(Stream, write_delimited_records(Columns, Delimiter)). write_delimited_records(Columns, Delimiter) :- ml_taketop(Columns, Top_Row, Columns1), write_delimited_record(Top_Row, Delimiter), write_delimited_records(Columns1, Delimiter). write_delimited_records(_, _). There's a general rule of thumb I call "garbage avoidance", except when I'm talking to people who've listened to Fred Dagg, when I call it the Bruce Bayliss Principle. (From a comedy skit: what should you do about all the garbage wrapping material? Bruce's idea: don't produce it in the first place.) SWI Prolog _can_ garbage collect the atom table, but why concatenation stuff in the first place if the only thing you are going to do with it is print it? write_delimited_record([Last], _) :- !, write(Last), nl. write_delimited_record([Item|Items], Delimiter) :- write(Item), write(Delimiter), write_delimited_record(Items, Delimiter). Of course, this misses one of the most important things in writing CSV-like files, and that is to insert any necessary quoting, but that's left as an exercise for the reader. > _______________________________________________ SWI-Prolog mailing list SWI-Prolog@... https://mailbox.iai.uni-bonn.de/mailman/listinfo.cgi/swi-prolog |
|
|
RE: Merging Lists and Writing Delimited RecordsParker From: MICHAEL.L.CARROLL@... To: swi-prolog@... Subject: [SWIPL] Merging Lists and Writing Delimited Records Date: Thu, 29 Oct 2009 18:42:33 -0700 All,
In case any of you might find these useful (I have), here are a couple of predicates that help merge lists of lists and produce delimited records (to be read by something like Excel). They seem to work fine for my work, but there may be corner cases where things fall apart. At any rate, have at it.
% The following little predicate will facilitate the merging of arbitrary number of lists: [...] New Windows 7: Find the right PC for you. Learn more. |
| Free embeddable forum powered by Nabble | Forum Help |