I’ve been lucky enough to work with and mentor some amazing developers during my time. Most recently I’ve had the pleasure of watching my apprentices take the leap from a junior role to solid mid-level positions – but even with that, I still like to keep them in-touch from time to time.
At the end of every Sprint I’ve started to set them a code Kata challenge, how they work on it – I don’t care, it can either be together, independently – or even battle it out against the clock. As long as they learn something new, have fun & enjoy themselves – I’m happy (and they get a coffee from me too ☕️).
One of the recent challenges was a Kata I was given some time ago for a job interview as. C# developer, the task was to write and interface to convert an Integer to Roman Numerals.
Now, it was some time back when I attempted this Kata (and I seemed to remember getting it working – I think) but I was very excited to see what and how my two team members would approach this.
The results are in…
Okay so this article is not so much about the Kata itself but the one of many ways to solve it – both approaches where great especially after only giving them 1 hour to do it in too.
One approach was very methodical and made for great code and logic separation, lending itself perfect to unit testing (and a way that would have been worthy of TDD approach).
Another made the use my good old friend ‘where’ clauses (see article here), and the enumerated() function – which we’ll take a look at this week.
So what & when can I use the enumerated() function?
So Apple’s official documentation says;
Returns a sequence of pairs (n, x), where n represents a consecutive integer starting at zero and x represents an element of the sequence
developer.apple.com
So lets take a quick look at this in code, we’ll iterate over a string and call the ‘enumerated()’ function;
for (index, letter) in "CocoaCabana".enumerated() { print("Index: \(index), Letter:\(letter)") }
The preceding code gives us the following results in our console;
Index: 0, Letter:C Index: 1, Letter:o Index: 2, Letter:c Index: 3, Letter:o Index: 4, Letter:a Index: 5, Letter:C Index: 6, Letter:a Index: 7, Letter:b Index: 8, Letter:a Index: 9, Letter:n Index: 10, Letter:a
Nice – so why would we want to use this (and how does this get my my coffee in the code Kata), let’s take a further look, below is one example of how to complete the Roman Numerals Kata;
let romanValues = ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"] let equivalentValues = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1] extension Int { func toRoman() -> String { var originalNumber = self var numeralString = String() while originalNumber > 0 { for (index, equivalentValue) in equivalentValues.enumerated() where originalNumber - equivalentValue >= 0 { originalNumber -= equivalentValue numeralString += romanValues[index] break } } return numeralString } }
Now, lets break it down to see how and why we are using enumeration;
For the sake of this article, we’re just going to concentrate on the use of the enumerated() function, above you can see from the above we have an array of equivalentValues, each one of these maps directly to Roman Numeral value (e.g. 900 = CM etc..) which we have stored nicely in our romanValues array – but in order to get the right index, we need to know what index we are at when iterating one our equivalentValues array.
Old school approach would have us doing this (Which works perfectly and does the job;
var count = 0 for (letter) in "CocoaCabana" { print("Index: \(count), Letter:\(letter)") count+=1 }
But with the enumerated() approach our code is a lot cleaner and easier to manage inside our iteration.
Imagine the above snippet with an additional 15 lines, various bit of logic and integrated function calls, if our count variable got lost, moved or put in the wrong place, we immediately put the integrity of our function at risk.
However with enumerated() – we what where we are all the time on every iteration.
Final note
How you now go on to utilise the use of enumerated() is up to you, but I find with functions like this – they are part of the ‘little things’ that not everyone remembers or even knows about and seeing them being used in almost real life examples such as the above Kata, is a great way to prove how they could potentially be used on a day to day basis.
Yes, we could have used another approach to bind our two arrays together in the Kata, but that’s not what this post was about, there’s always room for refactoring, we all know that 😝
If your interested in having a go at the Kata, feel free to download it from here and you can find the playground from this article here too.
Enjoy
C. 🥃