Just adding to @crater2150’s suggestions…
I’d consider applying the filtering at the Data
level. This would also provide a better API for passing the predicate as an argument instead of hardwiring a single filter, e.g.
def readCsvDatabase(
filename: String,
pred: Data => Boolean = Function.const(true)
): List[Data] =
???
…to be called as
readCsvDatabase("data/data.csv")
or
readCsvDatabase("data/data.csv", _.isValid == 1)
I’d also apply conversion to Data
and subsequent filtering while still on the iterator, before converting to a collection. This way, in the filtering case you’ll only need to fit the filtered result items in memory rather than the full unfiltered result. Further, as there is no dependency on the result from previous computations, no flatMap/for expression is actually required…
def parseLine(line: String): Data = ???
bufferedSource
.getLines()
.drop(1)
.map(parseLine)
.filter(pred)
.toList
Finally, the source should be closed after use - consider Using
or similar to ensure this.