Parsing into a Dictionary of [Int: [Int]]

December is here, and that means that it’s time for Advent of Code. I’ve adopted Swift Argument Parser in my repo of attempts so I can run one of my solutions with something like swift run AdventOfCodeRunner --year 2020 --day 5.

I have multiple years in here as I go and re-add older puzzles, and what I would really like to do is be able to run something like this:

swift run AdventOfCodeRunner --year 2015 --day 1 --day 2 --year 2020 --day 1 --day 2

This would parse to a Dictionary of type [Int: [Int]], where the key is the year and the value is an array of days. Is there a straightforward way to do this that I’m missing or am I going to have to parse everything manually?

There isn't support for that kind of interface in ArgumentParser — in particular, while you can collect an array of --year values and an array of --day values, there isn't anything currently* that would let you figure out the relative ordering.

In general, I don't think that kind of interface — with relative-order-dependent options — is particularly well-suited to the command line. Options and flags should be ordering-agnostic in most cases. Have you considered combining the year and day into a single piece with a delimiter? You could call your command like:

$ swift run AdventOfCodeRunner 2015:1 2015:2 2020:1 2020:2

...and then parse each value into an ExpressibleByArgument type that splits and converts the year and day.


*I've worked a bit on a metadata type that would let you see positioning information for the parsed values, but that's still a WIP (and would still require a bit of funky reshaping to get the data type you want).

1 Like