2

The 2htdp/batch-io library contains the useful read-csv-file procedure for reading a CSV file into a list. It takes a filename as its argument. Unfortunately, it does not take a string containing CSV as its argument. Suppose I have a CSV in a string variable and I want to use read-csv-file to parse it. Is there a way to avoid saving the CSV to a file just to be able to parse the CSV?

The documentation says:

reads the standard input device (until closed) or the content of file f and produces it as a list of lists of comma-separated values.

The standard input feature could probably be exploited to achieve this, but I don't know how to proceed with this idea.

Flux
  • 9,805
  • 5
  • 46
  • 92

2 Answers2

3

The 2htdp libraries are meant for beginners are thus are less flexible than other csv libraries. Therefore, you have two options:

  1. batch-io provides simulate-file which is something similar to what you want, but nothing as clean as wrapping your string in a function which makes it into a file like object:
> (simulate-file read-csv-file "test,test,test")
(list (list "test" "test" "test"))
  1. Use csv-reading (csv-reading must be downloaded but just (require csv-reading) and continue through the errors it gives you):
#lang racket
(require csv-reading)
> (csv->list "test,test,test")
(list (list "test" "test" "test"))

If batch-io were more general it would be take in a string? or an input-port? but it does not.

Flux
  • 9,805
  • 5
  • 46
  • 92
Ryan Schaefer
  • 3,047
  • 1
  • 26
  • 46
  • I am very surprised that the only built-in CSV reading functionality is inside a HtDP library! – Flux Nov 09 '20 at 22:03
2

I found a way to make read-csv-file read from a string instead:

> (require 2htdp/batch-io)
> (define csv-string "one,one,one\ntwo,two,two")
> (parameterize ([current-input-port (open-input-string csv-string)])
    (read-csv-file 'stdin))
'(("one" "one" "one") ("two" "two" "two"))

This works by changing the standard input to be the CSV string.

@Ryan Schaefer's answer about simulate-file is great, but I feel a bit uncomfortable with using functionality that is still "under development" and not properly documented. As simulate-file's documentation says:

Note: this form is under development and will be documented in a precise manner after it is finalized and useful for a wide audience.

Flux
  • 9,805
  • 5
  • 46
  • 92
  • Just a note for people worried that changing the standard input here might break things, they're using `parameterize` for just that reason: it only will make that change in the code block bounded by that call, and outside of that block, it will be as if nothing changed. – Lazerbeak12345 Nov 10 '20 at 15:20