Live data from Hacker News

World's Smallest CSV Parser (C#)

github.com

51–60 of 72 posts

Re: World's Smallest CSV Parser (C#)

#51
post #7

Earlier quoted context omitted.

There is no utility. It's perhaps written for JavaScript developers who are used to Error.. but it's not idiomatic C#. Might be indicative of a copilot too. The use of a class-scoped `StringBuilder` that only one method uses, and `ReadQuotedColumn`/`ReadNonQuotedColumn` yielding one character at a time, rather than accepting a the builder isn't a good sign either (for efficiency). Or casting everything to a `char` (t…

C# `char` is a UTF-16 code unit. It does not indicate a byte which is just `byte`. Having StringBuilder be a private field on the parser instance is not an issue either - it is simply reused.

> Having StringBuilder be a private field on the parser instance is not an issue either - it is simply reused.

It doesn’t matter for this API, but it is a code smell. It makes the class not reentrant.

Talking of the API, I would make it simpler to use and more idiomatic by making the entire public API

   static IEnumerable> parse(StreamReader sr)
That call would store the parser state (currently just the StreamReader and that reused StringBuilder) in a private inner class. There would not be a constructor of the publicly visible class, removing that code smell.

Re: World's Smallest CSV Parser (C#)

#52
post #43

Earlier quoted context omitted.

Do you need more than 1k of additional source to wrap the line parsing in a loop? I doubt it.

Linebreaks can be escaped in CSV, so splitting a file into rows is actually ~1/3 the complexity of parsing a whole row. See: https://github.com/semitrivial/csv_parser/blob/master/split.... Though I suppose that's the naive approach. You could combine the two into a single file by, like you say, wrapping the row-parser in a (clever, non-trivial) outer loop, and it probably wouldn't take anywhere near 1000 characters t…

> Linebreaks can be escaped in CSV

In some variants of CSV. There isn’t agreement on the format. For example, https://www.ietf.org/rfc/rfc4180.txt says

“While there are various specifications and implementations for the CSV format (for ex. [4], [5], [6] and [7]), there is no formal specification in existence, which allows for a wide variety of interpretations of CSV files.”

That RFC doesn’t even agree with itself, saying

“1. Each record is located on a separate line, delimited by a line break (CRLF).”

but then following that up with:

“6. Fields containing line breaks (CRLF), double quotes, and commas should be enclosed in double-quotes”

Re: World's Smallest CSV Parser (C#)

#53

That’s still multiple lines of code. Here’s one in c++ that uses only a single line of code (excluding function headers) // How do I format this as code? vector split( const string& s) { return accumulate(s.begin(), s.end(), vector (1), [=](auto acc, char c) { if (c == ‘,’){ acc.push_back(string()); } else { acc.back( ) += c; } return acc; } ); }

Does it parse this, though?

  "Verne, Jules", "20,000 leagues under the sea"

Re: World's Smallest CSV Parser (C#)

#54
post #43

Earlier quoted context omitted.

Do you need more than 1k of additional source to wrap the line parsing in a loop? I doubt it.

Linebreaks can be escaped in CSV, so splitting a file into rows is actually ~1/3 the complexity of parsing a whole row. See: https://github.com/semitrivial/csv_parser/blob/master/split.... Though I suppose that's the naive approach. You could combine the two into a single file by, like you say, wrapping the row-parser in a (clever, non-trivial) outer loop, and it probably wouldn't take anywhere near 1000 characters t…

Parse the whole file in one go. You need to track opening and closing quotes (and escaped ones) anyway, so there is no need to distinguish between commas (semicolons, tabs) and newlines.

Btw. you are not handling escaped double quotes in strings at all, and if you would do that you'd also need to count the number of backspaces. Oh, and no need to escape double quotes in single quotes ('\" could just be '"').

Re: World's Smallest CSV Parser (C#)

#55

What's the utility of defining the "Error" exception. Why not use an existing one, say InvalidOperationException, or a plain Exception. Is making your own better practice?

It's good practice to throw an exception from your own namespace if you're writing a library.

You don't want to expose an implementation detail like some specific exception as part of your public API and have to worry about breaking that later.

You could overload some built in exception but IMO that's not the best practice. You muddy your API and a caller has to wrap your exception if they want to bubble it up and catch it specifically, anyway.

Re: World's Smallest CSV Parser (C#)

#56
post #52
post #43

Earlier quoted context omitted.

Linebreaks can be escaped in CSV, so splitting a file into rows is actually ~1/3 the complexity of parsing a whole row. See: https://github.com/semitrivial/csv_parser/blob/master/split.... Though I suppose that's the naive approach. You could combine the two into a single file by, like you say, wrapping the row-parser in a (clever, non-trivial) outer loop, and it probably wouldn't take anywhere near 1000 characters t…

> Linebreaks can be escaped in CSV In some variants of CSV. There isn’t agreement on the format. For example, https://www.ietf.org/rfc/rfc4180.txt says “While there are various specifications and implementations for the CSV format (for ex. [4], [5], [6] and [7]), there is no formal specification in existence, which allows for a wide variety of interpretations of CSV files.” That RFC doesn’t even agree with itself, sa…

There is no contradiction, as (1) does not say that "each record is located on a (exactly one) single separate line". But it could be better phrased, like "two consecutive records are separated by...".

This is the "mathematical a", which does not mean "exactly one" but "at least one, and we don't care how many, we already did the interesting work". Like in "this problem has a solution".

Re: World's Smallest CSV Parser (C#)

#58
Yuck, that RFC 4180 actually quotes Postel's poorly considered "law" and recommends that it be followed. Why have a RFC then. If you're going to be liberal in what you accept, then the RFC is just a suggestion.

Plus it's not just defining CSV but actually a CSV MIME format (what?) and thus insists that since CSV is MIME wire data, it must use CR-LF line breaks, rather than assume that data can be converted to an operating system's text file format, and native line breaks.

You'd think that CSV could be defined without reference to MIME whatsoever, using abstract line breaks; and that it's a no-brainer that since it is text, it can be MIME-encoded as a plain text type.

Re: World's Smallest CSV Parser (C#)

#59

Questions: 1. What is the size of the install required to get C# to run on a computer without Windows or MacOS installed 2. What is the size of the install for this C# library Just curious

If UNIX means "a certified unix that isn't MacOS" the answer is 0 bytes (actually more like 0/0 bytes).

Re: World's Smallest CSV Parser (C#)

#60
post #15

Very nice. The submission's main file (SmallestCSVParser.cs) is 3851 characters (of which 657 are commentary). Mine, in C, is only 2807 characters (of which 198 are commentary): https://github.com/semitrivial/csv_parser/blob/master/csv.c Ahh, but the submission's main file is for parsing an entire .csv, whereas mine is only for parsing a single "line" (possibly including quote-escaped newlines). So the submission win…

Back in the days (2008) i created an Autohotkey v1 function for parsing a delimiter seperated line called ReturnDSVArray

it can be found here: https://www.autohotkey.com/board/topic/30102-how-can-i-parse...

it consists of some 30ish lines of code and 67 lines with comments and usage example

Post reply on HN