| 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(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(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).
Note: versions before 9.3.33 must use library(http/json) instead of library(json).
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.