0

I have this code in my Roman Numeral conversion algorithm...

for (a, r) in arabicToRomanArray where substring.hasPrefix(r) {
    arabic += a
    let index = substring.index(substring.startIndex, offsetBy: r.characters.count)
    substring = substring.substring(from: index)
    break
}

I was wondering if there is an easier way of doing this.

At the moment I am doing a conditional for loop and then breaking on the first entry. Is there a way to do a for first type block with the condition?

The only way I can think of doing it is to filter the array and then get the first object from the filtered array and use that. Seems clunkier than what I'm doing at the moment though.

Edit

After trying out the edit it also makes the algorithm much slower, which makes sense.

The for/break loop will have a best time of O(1) and worst time of O(n).

The filter and first method will have a best time of O(n).

Fogmeister
  • 76,236
  • 42
  • 207
  • 306

1 Answers1

0

Thanks to @MartinR's comment I found a much better way of doing the same thing.

It's equivalent in time to the for/break loop but less clunky.

The code I had previously...

for (a, r) in arabicToRomanArray where substring.hasPrefix(r) {
    arabic += a
    let index = substring.index(substring.startIndex, offsetBy: r.characters.count)
    substring = substring.substring(from: index)
    break
}

Is now...

let (a, r) = arabicToRomanArray[arabicToRomanArray.index(where:{string.hasPrefix($0.1)})!]
arabic += a
let index = substring(substring.startIndex, offsetBy: numCharacters)
substring = substring.substring(from: index)

Using the array function...

array.index(where: (Element) -> Bool)

like...

arabicToRomanArray.index(where:{string.hasPrefix($0.1)})

I also refactored out some of the code into functions once I'd done this so it's actually now...

let (a, r) = findPrefixedArabicToRoman(string: substring)
arabic += a
substring = remove(numCharacters: r.characters.count, fromString: substring)
Fogmeister
  • 76,236
  • 42
  • 207
  • 306