ozataman / csv-conduit

Flexible, fast and constant-space CSV library for Haskell using conduits
Other
52 stars 32 forks source link

MapRow does not preserve header order #40

Closed 5outh closed 3 years ago

5outh commented 3 years ago

With the given input file:

b,a
1,foo

Running this program:

myProcessor :: MonadIO m => ConduitT (MapRow Text) (MapRow Text) m ()
myProcessor = CC.filter id

runResourceT
    $ runConduit
    $ CC.sourceFile "in.csv"
    .| intoCSV defCSVSettings
    .| myProcessor
    .| (writeHeaders defCSVSettings >> fromCSV defCSVSettings)
    .| CC.sinkFile "out.csv"

outputs the following to out.csv:

a,b
foo,1

It would be nice to preserve the ordering as determined by the header, or at least have the option to do so.

ysangkok commented 3 years ago

It just bit me that rowToStr also is affected by this, subsequent calls to it are technically not guaranteed to have the same order...

I wish NamedRecord was an OrderedMap instead. I order the keys when I pass them to namedRecord...

MichaelXavier commented 3 years ago

I would accept an MR to use probably [https://hackage.haskell.org/package/ordered-containers] to solve this problem. The impact seems significant enough that it would be worth making a breaking change than to try to preserve the old behavior. I can't imagine anyone is relying on the current implementation to put the keys in alphabetical order because that's how Map stores them.