Headers

Scautable supports flexible header handling using the HeaderOptions enum. This allows fine-grained control over how headers are extracted or constructed from CSV input.

Available Options

TODO: Link scaladoc

AutoGenerated

Creates headers automatically:

import io.github.quafadas.table.*
import io.github.quafadas.scautable.HeaderOptions
inline val csvContent = "Name,Age\nFirst,Years\nAlice,30\nBob,24"
// csvContent: String = """Name,Age
// First,Years
// Alice,30
// Bob,24"""

val multiLine = CSV.fromString(csvContent, HeaderOptions.AutoGenerated)
// multiLine: CsvIterator[Tuple2["col_0", "col_1"], *:[String, *:[String, EmptyTuple]]] = non-empty iterator
multiLine.headers
// res0: Seq[String] = Vector("col_0", "col_1")

Useful when your CSV has no headers or you're working with raw tabular data.

Manual

Provides explicit header names:

import io.github.quafadas.table.*
import io.github.quafadas.scautable.HeaderOptions

val manual = CSV.fromString("1,2,3", HeaderOptions.Manual("a", "b", "c"))
// manual: CsvIterator[Tuple3["a", "b", "c"], *:[String, *:[String, *:[String, EmptyTuple]]]] = empty iterator
manual.headers
// res1: Seq[String] = ArraySeq("a", "b", "c")
manual.toSeq
// res2: Seq[NamedTuple[Tuple3["a", "b", "c"], *:[String, *:[String, *:[String, EmptyTuple]]]]] = List(
//   ("1", "2", "3")
// )

FromRows

Combines multiple rows from the start of the file into multi-line headers. Also allows skipping initial metadata rows.

Behavior:

Example:

import io.github.quafadas.table.*
import io.github.quafadas.scautable.HeaderOptions
inline val csvContent = "Name,Age\nFirst,Years\nAlice,30\nBob,24"
// csvContent: String = """Name,Age
// First,Years
// Alice,30
// Bob,24"""

val multiLine = CSV.fromString(csvContent, HeaderOptions.FromRows(merge = 2))
// multiLine: CsvIterator[Tuple2["Name First", "Age Years"], *:[String, *:[String, EmptyTuple]]] = non-empty iterator
multiLine.headers
// res4: Seq[String] = List("Name First", "Age Years")

This is useful when your data source encodes hierarchical or descriptive headers across multiple lines.

HeaderOptions.Default Behavior

The default configuration is:

import io.github.quafadas.scautable.HeaderOptions

HeaderOptions.FromRows(merge = 1, dropFirst = 0)
// res5: HeaderOptions = FromRows(merge = 1, dropFirst = 0)

Which corresponds to the traditional single-row header handling.

Header deduplication

If you are in the situation where you have a large number of duplicate headers, consider de-duplication.

val csvDup: CsvIterator[("colA", "colA", "colA", "colB", "colC", "colA"), (String, String, String, String, String, String)] = CSV.resource("dups.csv")

val dedupCsv: CsvIterator[("colA", "colA_1", "colA_2", "colB", "colC", "colA_5"), (String, String, String, String, String, String)] = CSV.deduplicateHeader(csvDup)