I have a record type which holds a list of table rows. Each row is also a list. The first row is assumed to be the header row. In addition the type optionally defines a filter - a list of columns (the actual string value of the column header).
Then the type have a member property FilteredRows
. If no filter is defined, the property is the entire table. But if there is a filter, FilteredRows
return the list of rows, but only with the columns defined by the filter.
I'm not interested in alternative ways to represent this. This is part of a bigger solution, it's working, and the design makes sense to me. What I believe I need however is some more eyes on the internals of FilteredRows
. I'm looking for clever tricks on solving this problem in different ways, and other pointers on how I can improve the solution.
type Table =
{
Rows : string list list
OnlyColumns : string list option
}
member internal x.FilteredRows =
match x.OnlyColumns with
| None -> x.Rows
| Some xs ->
let indexesToInclude = seq {
let headers = List.head x.Rows
for c in xs do
yield List.findIndex ((=) c) headers }
x.Rows
|> List.map
(fun row ->
indexesToInclude
|> Seq.map (List.nth row)
|> List.ofSeq )
As you can see, what I've done is first to fetch all the column indexes using List.findIndex
. And then for each row I map over the column indices and re-create the row using List.nth
.