HomeForumResearchGuide
<< back to How To home

This program shows how we can parse a CSV file and perform basic queries such as sorting or searching for values.

Let's assume that we have an input CSV file which looks like this:

id, colour, score
22, Blue, 2.0
26, Red, 27.924
30, Green, 0.001

To parse this in Dana, we start by defining a data type which matches the expected format in the file, then use the CSVParser. Create a new file App.dn and open it in a text editor. We're going to use the data.csv.CSVParser interface, the io.File interface to read data in from a file, and the command-line output interface:

data Row {
	int id
	char colour[]
	dec score
	}

component provides App requires io.Output out, data.IntUtil iu, data.csv.CSVParser parser, io.File {
	
}

The App interface has one function called main. Any executable component will implement App, indicating it has a main method that Dana can launch. We've defined a data type called Row which matches the expected data format in each row, including the expected types of each field. This acts as a template for the CSV parser so that it knows which data types to expect in the CSV file.

We now implement our App interface, which we'll do like this:

data Row {
	int id
	char colour[]
	dec score
	}

component provides App requires io.Output out, data.IntUtil iu, data.csv.CSVParser parser, io.File {

int App:main(AppParam params[])
	{
	File fd = new File("input.csv", File.READ)
	
	Row rows[] = parser.parseDocument(fd, true, ",", new Row())
	
	out.println("parsed $(rows.arrayLength) rows")
	
	return 0
	}

}

This program first opens a file for reading, assuming it's called input.csv and is in the local directory. It then passes this file object into the CSV parser to parse the file, indicating that the first line of the file is a header line, specifying the column separator, and providing the data instance template.

The parseDocument function will parse all rows in the file and return them as an array. We can then iterate over the array, or use data query operations such as searching or sorting.

We can now compile the program using the Dana compiler. Open a command-prompt in the directory containing your source code file and type:

dnc App.dn

And pressing enter. This will compile your component.

We run the program using Dana's interpreter by typing:

dana App

And pressing enter. Assuming that the expected CSV file is in the local directory you should see the total number of rows that were parsed.

If we wanted to sort the rows by the id' column we could simply add the data.query.Sort interface to our list of required interfaces, as data.query.Sort sort, then just add the line:

rows = rows.sort(Row.[id])

Or if we want to search for rows matching a given column value, such as a particular colour, we could add the data.query.Search interface to our list of required interfaces, as data.query.Search search, then use the line:

Row res[] = rows.find(Row.[colour], new Row(colour = "Blue"))

The full list of standard interfaces that you can use in requires directives can be viewed at the Dana API pages along with documentation of each one. In this example we used: