Did you know ... | Search Documentation: |
Predicate =/2 |
=(Term, Term).
For behaviour on cyclic terms see the Prolog flag occurs_check. Calls to =/2 in a clause body are compiled and may be (re)moved depending on the Prolog flag optimise_unify. See also section 2.17.3.
?- length(L, 5), maplist(=(foo), L). L = [foo, foo, foo, foo, foo].
With the help of library(csv) and library(http/json), we read a CSV file and use the column names in the first row to emit JSON.
For this example, we use the file weather.csv
:
city,temp_lo,temp_hi,prcp,date San Francisco,46,50,0.25,1994-11-27 San Francisco,43,57,0,1994-11-29 Hayward,37,54,,1994-11-29
The script csv_to_json.pl
reads the CSV from standard input or from
the file provided as the first argument of the script. It converts
the contents to a list of dicts, then writes this as JSON to standard
output:
:- initialization(main, main). :- use_module(library(csv)). :- use_module(library(http/json)). main :- ( current_prolog_flag(argv, [CSV_file|_]) -> csv_read_file(CSV_file, CSV, []) ; csv_read_stream(current_input, CSV, []) ), CSV = [Colnames|Rows], Colnames =.. [row|Names], maplist(row_dict(Names), Rows, Dicts), json_write_dict(current_output, Dicts, [null('')]). row_dict(Names, Row, Dict) :- Row =.. [row|Fields], pairs_keys_values(Data, Names, Fields), dict_create(Dict, _, Data).
The null('')
option to json_write_dict/3 is necessary to convert the
empty "prcp" field in the last row to a missing value represented as
null
in the JSON output.
This is how we can use it to convert weather.csv
to JSON:
$ swipl csv_to_json.pl weather.csv [ { "city":"San Francisco", "date":"1994-11-27", "prcp":0.25, "temp_hi":50, "temp_lo":46 }, { "city":"San Francisco", "date":"1994-11-29", "prcp":0, "temp_hi":57, "temp_lo":43 }, { "city":"Hayward", "date":"1994-11-29", "prcp":null, "temp_hi":54, "temp_lo":37 } ]
file_line(File, Line) :- setup_call_cleanup(open(File, read, In), stream_line(In, Line), close(In)). stream_line(In, Line) :- repeat, ( read_line_to_string(In, Line0), Line0 \== end_of_file -> Line0 = Line ; !, fail ).
This will backtrack over consecutive lines in the input. If we use the Unix dictionary words:
?- file_line("/usr/share/dict/words", Word). Word = "A" ; Word = "a" ; Word = "aa" ; Word = "aal" ; % and so on
This doesn't load all lines to memory, so it can be used with very large files.