My code is below. It seems like the data gets output in a random order, which makes sense since NamedRecord
is just a Map
. Is there a way I can enforce a specific order?
I think one option is to create a conduit of type Conduit (Named a) m (Row Text)
, but it seems like this is a common enough use case that something standard should already exist.
processor :: Monad m => Conduit (Named FalconRow) m (Named HefRow)
processor = do
value <- await
case value of
Nothing -> return ()
Just v -> do
let transformed = (fixRow . getNamed) v
CL.sourceList $ Prelude.map Named transformed
runTranslation :: IO ()
runTranslation = runResourceT $
transformCSV defCSVSettings
(sourceFile "input.csv")
processor
(sinkFile "output.csv")
I ended up just making my own function for this:
sortColumns :: (Monad m, DefaultOrdered a, ToNamedRecord a) => Conduit (Named a) m (Row ByteString)
sortColumns = CL.map doSort
doSort :: (DefaultOrdered a, ToNamedRecord a) => Named a -> Row ByteString
doSort value =
let columnMap = toNamedRecord $ getNamed value
headers = toList $ headerOrder $ getNamed value
bsValue = map (\title -> findWithDefault "" title columnMap) headers
in bsValue