One line CSV parser with Swift (The power of Swift)

We developing new game in ALSEDI and one of the tasks is parsing of CSV-like format. I find that it’s really fun and simple task with Swift.

CSV format may contain complex and sometimes style-breaking elements, like comma between quotes. If you have this case then you need to use more powerful parsing methods, like regex.

However, for simple data types which do not try to make a chaos in your data structure, CSV is very handy and much more readable than JSON. This article is about parsing this kind of CSV and about how simple is this.

Long story short, here is the one-line CSV parser.

Complete parsing is in this code content.components(separatedBy: "\n").map{ $0.components(separatedBy: ",") }

What’s happening here.

  1. String is sliced to an array at positions of new line symbol. It is the same as lines in text file.
  2. This array used as input for map function which calls the same slicing method for each sub string. On this step comma is used for slicing. In the result we have content of every line content represented as array
  3. Array of array of strings is returned and assigned to parsedCSV

It’s simplest parsing without error or memory issues handling. These topics deserve separate explanation. However, it’s handy for small configs and data collections, like configs.

We can do one more thing. Current solution returns arrays of strings, but CSV may¬†contains several¬†data types. Let’s try to parse and return arrays of mixed String, Int and Double values.

In Swift we aren’t allowed to define several types as¬†array type and Any type isn’t what is good for us (still usable, but not swifty).

Well… How to combine different types¬†in one array then. Hmm.. with protocols! It’s fine to write your own protocol, but¬†types we need conform to CustomStringConvertible protocol¬†and we will use it as a type of elements in 2D array.

It’s not enough just to change type of elements and we need to check each value for a type and return correct in result of “map”. Otherwise all of them will be Strings.

We cannot use Array.filter because it returns the same type as it gets from input, so we will use Array.map again.

That’s it.

Step one is the same as above, but step two adds additional mapping. Inside that Array.map you get value of type String but it can¬†return any type.¬†¬†That’s why it is important to define type of parsedCSV and do not rely on type inference. You may not do it but it will not guarantee that in your own cases you will get type-expected results.

p.s. Array.filter is extremely useful if you need to cleanup input CSV from values of specific type. For example, this code returns arrays of Strings but them contain values which can be converted to Int.


Subscribe to weekly digest to keep updated on news about Swift, iOS and Android.


Leave a Reply

Your email address will not be published. Required fields are marked *