Converting a table to an Array of Maps

Problem statement

To import data organized in a tabular form.

The table

This assumes that the first row of the table is a header row giving names for the columns, and the remaining rows are data with the same number of columns.

Input

As a running example:

If we export this from a spreadsheet, using the tab-separated values format, we will get a String (called content in the sample code later).

Exporting the table

The exact technique will depend on the database or the spreadsheet holding the input table. To do such an export from Google sheets, the UX menu choice would look like this:

And the downloaded file, in hexdump -C format would look like this:

00000000 41 09 42 0d 0a 31 09 32 0d 0a 33 09 34 |A.B..1.2..3.4|

with Windows line separators (note nothing for the final line), or like this:

00000000 41 09 42 0a 31 09 32 0a 33 09 34 0a |A.B.1.2.3.4. |

with UNIX line terminators, in this case including for the final line.

Output

What we would like to work with in KRL is an Array with one entry for each line (row) of data, where each line of data becomes a Map (using the keys from row one of the input table):

[ {"A": "1", "B": "2"}, {"A": "3", "B", "4"} ]

Compare this to the original table, shown again here for convenience:

The transforming KRL code

Handling line termination

We need a pattern that matches either the Window line separators or the UNIX line terminators.

Handling the lines

This code fragment will split the content into lines, and call the first line, separated by tabs, keys:

Handling each data line

Each data line will need to be transformed from "1\t2"` into the Map {"A":"1","B":"2"}` for example.

We have committed to define a function named lineToMap to do this (line 6). It will need access to the keys so we must define it inside the TSVtoArrayOfMap function:

The comment on each line shows the value bound/produced on the line. For the lineToMap function, which will be called twice, we are using the second line of data. The first would be processed in the same manner.

Handling empty lines

In the case where there is a line terminator after the final line, this code would fail in the pairwise function (line 5) because the keys and data arrays would not be of the same size.

So better to remove the empty line before applying the lineToMap function:

which takes advantage of the fact that an empty String is not truthy, and so any empty line will be ignored in the output.

Copyright Picolabs | Licensed under Creative Commons.