Swift function to interpret Roman numerals (ported from JavaScript)

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
5
down vote

favorite
1












I have written some Swift for the first time, being competent enough in Javascript and having some experience in Ruby and Python. For my education, I've written a function that parses a roman numeral string and returns its integer representation, first in Javascript (ES2015+):




const dict = [
['CM', 900], ['M', 1000], ['CD', 400], ['D', 500],
['XC', 90], ['C', 100], ['XL', 40], ['L', 50],
['IX', 9], ['X', 10], ['IV', 4], ['V', 5],
['I', 1],
]

function romanToInt (original)
let temp = original
let int = 0

while (temp.length > 0)
let found = false

for (const [glyph, quantity] of dict)
if (temp.startsWith(glyph))
int += quantity
temp = temp.slice(glyph.length)
found = true
break



if (!found)
// e.g. Error parsing roman numeral "MDCCLXXVI," at ","
throw new Error(`Error parsing roman numeral "$original" at "$temp"`)



return int


try
romanToInt('MMXIV') // => 2014
catch (err)
console.error(err)




and then ported it to Swift 4:



let dict: [( glyph: String, quantity: Int )] = [
("CM", 900), ("M", 1000), ("CD", 400), ("D", 500),
("XC", 90), ("C", 100), ("XL", 40), ("L", 50),
("IX", 9), ("X", 10), ("IV", 4), ("V", 5),
("I", 1)
]

enum RomanNumericError: Error
case badInput(original: String, temp: String)


func romanToInt(original: String) throws -> Int
var temp = original
var int = 0

while temp.count > 0
var found = false

for (glyph, quantity) in dict
if temp.starts(with: glyph)
int += quantity
temp.removeFirst(glyph.count)
found = true
break



guard found == true else
throw RomanNumericError.badInput(original: original, temp: temp)



return int


do
try romanToInt(original: "MMXIV") // => 2014
catch RomanNumericError.badInput(let original, let temp)
print("Error parsing roman numeral '(original)' at '(temp)'")



I'm wondering about how swift-y my code is in terms of design patterns, especially in terms of error handling. In Javascript, throwing and catching errors is a very common control flow design, and I'm wondering if I'm approaching it from the right angle in Swift.







share|improve this question



























    up vote
    5
    down vote

    favorite
    1












    I have written some Swift for the first time, being competent enough in Javascript and having some experience in Ruby and Python. For my education, I've written a function that parses a roman numeral string and returns its integer representation, first in Javascript (ES2015+):




    const dict = [
    ['CM', 900], ['M', 1000], ['CD', 400], ['D', 500],
    ['XC', 90], ['C', 100], ['XL', 40], ['L', 50],
    ['IX', 9], ['X', 10], ['IV', 4], ['V', 5],
    ['I', 1],
    ]

    function romanToInt (original)
    let temp = original
    let int = 0

    while (temp.length > 0)
    let found = false

    for (const [glyph, quantity] of dict)
    if (temp.startsWith(glyph))
    int += quantity
    temp = temp.slice(glyph.length)
    found = true
    break



    if (!found)
    // e.g. Error parsing roman numeral "MDCCLXXVI," at ","
    throw new Error(`Error parsing roman numeral "$original" at "$temp"`)



    return int


    try
    romanToInt('MMXIV') // => 2014
    catch (err)
    console.error(err)




    and then ported it to Swift 4:



    let dict: [( glyph: String, quantity: Int )] = [
    ("CM", 900), ("M", 1000), ("CD", 400), ("D", 500),
    ("XC", 90), ("C", 100), ("XL", 40), ("L", 50),
    ("IX", 9), ("X", 10), ("IV", 4), ("V", 5),
    ("I", 1)
    ]

    enum RomanNumericError: Error
    case badInput(original: String, temp: String)


    func romanToInt(original: String) throws -> Int
    var temp = original
    var int = 0

    while temp.count > 0
    var found = false

    for (glyph, quantity) in dict
    if temp.starts(with: glyph)
    int += quantity
    temp.removeFirst(glyph.count)
    found = true
    break



    guard found == true else
    throw RomanNumericError.badInput(original: original, temp: temp)



    return int


    do
    try romanToInt(original: "MMXIV") // => 2014
    catch RomanNumericError.badInput(let original, let temp)
    print("Error parsing roman numeral '(original)' at '(temp)'")



    I'm wondering about how swift-y my code is in terms of design patterns, especially in terms of error handling. In Javascript, throwing and catching errors is a very common control flow design, and I'm wondering if I'm approaching it from the right angle in Swift.







    share|improve this question























      up vote
      5
      down vote

      favorite
      1









      up vote
      5
      down vote

      favorite
      1






      1





      I have written some Swift for the first time, being competent enough in Javascript and having some experience in Ruby and Python. For my education, I've written a function that parses a roman numeral string and returns its integer representation, first in Javascript (ES2015+):




      const dict = [
      ['CM', 900], ['M', 1000], ['CD', 400], ['D', 500],
      ['XC', 90], ['C', 100], ['XL', 40], ['L', 50],
      ['IX', 9], ['X', 10], ['IV', 4], ['V', 5],
      ['I', 1],
      ]

      function romanToInt (original)
      let temp = original
      let int = 0

      while (temp.length > 0)
      let found = false

      for (const [glyph, quantity] of dict)
      if (temp.startsWith(glyph))
      int += quantity
      temp = temp.slice(glyph.length)
      found = true
      break



      if (!found)
      // e.g. Error parsing roman numeral "MDCCLXXVI," at ","
      throw new Error(`Error parsing roman numeral "$original" at "$temp"`)



      return int


      try
      romanToInt('MMXIV') // => 2014
      catch (err)
      console.error(err)




      and then ported it to Swift 4:



      let dict: [( glyph: String, quantity: Int )] = [
      ("CM", 900), ("M", 1000), ("CD", 400), ("D", 500),
      ("XC", 90), ("C", 100), ("XL", 40), ("L", 50),
      ("IX", 9), ("X", 10), ("IV", 4), ("V", 5),
      ("I", 1)
      ]

      enum RomanNumericError: Error
      case badInput(original: String, temp: String)


      func romanToInt(original: String) throws -> Int
      var temp = original
      var int = 0

      while temp.count > 0
      var found = false

      for (glyph, quantity) in dict
      if temp.starts(with: glyph)
      int += quantity
      temp.removeFirst(glyph.count)
      found = true
      break



      guard found == true else
      throw RomanNumericError.badInput(original: original, temp: temp)



      return int


      do
      try romanToInt(original: "MMXIV") // => 2014
      catch RomanNumericError.badInput(let original, let temp)
      print("Error parsing roman numeral '(original)' at '(temp)'")



      I'm wondering about how swift-y my code is in terms of design patterns, especially in terms of error handling. In Javascript, throwing and catching errors is a very common control flow design, and I'm wondering if I'm approaching it from the right angle in Swift.







      share|improve this question













      I have written some Swift for the first time, being competent enough in Javascript and having some experience in Ruby and Python. For my education, I've written a function that parses a roman numeral string and returns its integer representation, first in Javascript (ES2015+):




      const dict = [
      ['CM', 900], ['M', 1000], ['CD', 400], ['D', 500],
      ['XC', 90], ['C', 100], ['XL', 40], ['L', 50],
      ['IX', 9], ['X', 10], ['IV', 4], ['V', 5],
      ['I', 1],
      ]

      function romanToInt (original)
      let temp = original
      let int = 0

      while (temp.length > 0)
      let found = false

      for (const [glyph, quantity] of dict)
      if (temp.startsWith(glyph))
      int += quantity
      temp = temp.slice(glyph.length)
      found = true
      break



      if (!found)
      // e.g. Error parsing roman numeral "MDCCLXXVI," at ","
      throw new Error(`Error parsing roman numeral "$original" at "$temp"`)



      return int


      try
      romanToInt('MMXIV') // => 2014
      catch (err)
      console.error(err)




      and then ported it to Swift 4:



      let dict: [( glyph: String, quantity: Int )] = [
      ("CM", 900), ("M", 1000), ("CD", 400), ("D", 500),
      ("XC", 90), ("C", 100), ("XL", 40), ("L", 50),
      ("IX", 9), ("X", 10), ("IV", 4), ("V", 5),
      ("I", 1)
      ]

      enum RomanNumericError: Error
      case badInput(original: String, temp: String)


      func romanToInt(original: String) throws -> Int
      var temp = original
      var int = 0

      while temp.count > 0
      var found = false

      for (glyph, quantity) in dict
      if temp.starts(with: glyph)
      int += quantity
      temp.removeFirst(glyph.count)
      found = true
      break



      guard found == true else
      throw RomanNumericError.badInput(original: original, temp: temp)



      return int


      do
      try romanToInt(original: "MMXIV") // => 2014
      catch RomanNumericError.badInput(let original, let temp)
      print("Error parsing roman numeral '(original)' at '(temp)'")



      I'm wondering about how swift-y my code is in terms of design patterns, especially in terms of error handling. In Javascript, throwing and catching errors is a very common control flow design, and I'm wondering if I'm approaching it from the right angle in Swift.









      share|improve this question












      share|improve this question




      share|improve this question








      edited Jan 26 at 23:09









      200_success

      123k14143401




      123k14143401









      asked Jan 26 at 20:52









      Christophe Marois

      1284




      1284




















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          4
          down vote



          accepted










          Let's do this from inside out. temp.starts(with: glyph) is correct, but
          there is also a dedicated method temp.hasPrefix(glyph) for strings.



          The loop to find the first dictionary entry with a matching prefix
          can be shortened to



          guard let (glyph, quantity) = dict.first(where: temp.hasPrefix($0.glyph) ) else 
          throw RomanNumericError.badInput(original: original, temp: temp)



          (also making the var found obsolete.)



          Mutating the temporary string can be avoided by working with a SubString (which is a kind of view into the original string) and
          only updating the current search position:



          var pos = original.startIndex
          while pos != original.endIndex
          let subString = original[pos...]
          // ...
          pos = original.index(pos, offsetBy: glyph.count)



          Naming: This is very opinion-based, here are my opinions:



          • Declare the function as func romanToInt(_ roman: String),
            so that it is called without (external) argument name:
            romanToInt("MMXIV").

          • Rename var int to var value.


          • dict is also a non-descriptive name (and it is not even a dictionary), something like glyphsAndValues might be a better choice.

          Summarizing the suggestions so far, we have



          func romanToInt(_ roman: String) throws -> Int 
          var value = 0
          var pos = roman.startIndex
          while pos != roman.endIndex
          let subString = roman[pos...]
          guard let (glyph, quantity) = glyphsAndValues.first(where: subString.hasPrefix($0.glyph) ) else
          throw RomanNumericError.badInput(roman: roman, at: subString)

          value += quantity
          pos = roman.index(pos, offsetBy: glyph.count)

          return value




          Now the error handling. Yes, throwing an error is a good and Swifty
          way to report a failure to the caller. (An alternative is to return an
          optional value which is nil in the error case, but that does not
          allow to provide additional error information.)



          The creation of the error message however should be done in the
          error class, by adopting the LocalizedError protocol:



          enum RomanNumericError: Error 
          case badInput(roman: String, at: Substring)


          extension RomanNumericError: LocalizedError
          public var errorDescription: String?
          switch self
          case .badInput(let roman, let at):
          return "Error parsing roman numeral '(roman)' at '(at)'"





          The big advantage is that the caller does not need to know which
          error the function throws, and can catch a generic Error:



          do 
          try print(romanToInt("MMXIV"))
          try print(romanToInt("MMYXIV"))
          catch
          print(error.localizedDescription)


          // Output:
          // 2014
          // Error parsing roman numeral 'MMYXIV' at 'YXIV'





          share|improve this answer























          • Really helpful, thank you. I have trouble using the LocalizedError protocol though; it throws a error: use of undeclared type 'LocalizedError' (Xcode 9.2, in a playground). I'm investigating why, but if you have a clue, I'd be glad to hear it.
            – Christophe Marois
            Jan 26 at 23:29










          • You may need to import Foundation.
            – Martin R
            Jan 26 at 23:33










          • Thanks, your comment and this thread stackoverflow.com/questions/33943477/… clarified the situation.
            – Christophe Marois
            Jan 26 at 23:36










          Your Answer




          StackExchange.ifUsing("editor", function ()
          return StackExchange.using("mathjaxEditing", function ()
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          );
          );
          , "mathjax-editing");

          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "196"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          convertImagesToLinks: false,
          noModals: false,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );








           

          draft saved


          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f186087%2fswift-function-to-interpret-roman-numerals-ported-from-javascript%23new-answer', 'question_page');

          );

          Post as a guest






























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          4
          down vote



          accepted










          Let's do this from inside out. temp.starts(with: glyph) is correct, but
          there is also a dedicated method temp.hasPrefix(glyph) for strings.



          The loop to find the first dictionary entry with a matching prefix
          can be shortened to



          guard let (glyph, quantity) = dict.first(where: temp.hasPrefix($0.glyph) ) else 
          throw RomanNumericError.badInput(original: original, temp: temp)



          (also making the var found obsolete.)



          Mutating the temporary string can be avoided by working with a SubString (which is a kind of view into the original string) and
          only updating the current search position:



          var pos = original.startIndex
          while pos != original.endIndex
          let subString = original[pos...]
          // ...
          pos = original.index(pos, offsetBy: glyph.count)



          Naming: This is very opinion-based, here are my opinions:



          • Declare the function as func romanToInt(_ roman: String),
            so that it is called without (external) argument name:
            romanToInt("MMXIV").

          • Rename var int to var value.


          • dict is also a non-descriptive name (and it is not even a dictionary), something like glyphsAndValues might be a better choice.

          Summarizing the suggestions so far, we have



          func romanToInt(_ roman: String) throws -> Int 
          var value = 0
          var pos = roman.startIndex
          while pos != roman.endIndex
          let subString = roman[pos...]
          guard let (glyph, quantity) = glyphsAndValues.first(where: subString.hasPrefix($0.glyph) ) else
          throw RomanNumericError.badInput(roman: roman, at: subString)

          value += quantity
          pos = roman.index(pos, offsetBy: glyph.count)

          return value




          Now the error handling. Yes, throwing an error is a good and Swifty
          way to report a failure to the caller. (An alternative is to return an
          optional value which is nil in the error case, but that does not
          allow to provide additional error information.)



          The creation of the error message however should be done in the
          error class, by adopting the LocalizedError protocol:



          enum RomanNumericError: Error 
          case badInput(roman: String, at: Substring)


          extension RomanNumericError: LocalizedError
          public var errorDescription: String?
          switch self
          case .badInput(let roman, let at):
          return "Error parsing roman numeral '(roman)' at '(at)'"





          The big advantage is that the caller does not need to know which
          error the function throws, and can catch a generic Error:



          do 
          try print(romanToInt("MMXIV"))
          try print(romanToInt("MMYXIV"))
          catch
          print(error.localizedDescription)


          // Output:
          // 2014
          // Error parsing roman numeral 'MMYXIV' at 'YXIV'





          share|improve this answer























          • Really helpful, thank you. I have trouble using the LocalizedError protocol though; it throws a error: use of undeclared type 'LocalizedError' (Xcode 9.2, in a playground). I'm investigating why, but if you have a clue, I'd be glad to hear it.
            – Christophe Marois
            Jan 26 at 23:29










          • You may need to import Foundation.
            – Martin R
            Jan 26 at 23:33










          • Thanks, your comment and this thread stackoverflow.com/questions/33943477/… clarified the situation.
            – Christophe Marois
            Jan 26 at 23:36














          up vote
          4
          down vote



          accepted










          Let's do this from inside out. temp.starts(with: glyph) is correct, but
          there is also a dedicated method temp.hasPrefix(glyph) for strings.



          The loop to find the first dictionary entry with a matching prefix
          can be shortened to



          guard let (glyph, quantity) = dict.first(where: temp.hasPrefix($0.glyph) ) else 
          throw RomanNumericError.badInput(original: original, temp: temp)



          (also making the var found obsolete.)



          Mutating the temporary string can be avoided by working with a SubString (which is a kind of view into the original string) and
          only updating the current search position:



          var pos = original.startIndex
          while pos != original.endIndex
          let subString = original[pos...]
          // ...
          pos = original.index(pos, offsetBy: glyph.count)



          Naming: This is very opinion-based, here are my opinions:



          • Declare the function as func romanToInt(_ roman: String),
            so that it is called without (external) argument name:
            romanToInt("MMXIV").

          • Rename var int to var value.


          • dict is also a non-descriptive name (and it is not even a dictionary), something like glyphsAndValues might be a better choice.

          Summarizing the suggestions so far, we have



          func romanToInt(_ roman: String) throws -> Int 
          var value = 0
          var pos = roman.startIndex
          while pos != roman.endIndex
          let subString = roman[pos...]
          guard let (glyph, quantity) = glyphsAndValues.first(where: subString.hasPrefix($0.glyph) ) else
          throw RomanNumericError.badInput(roman: roman, at: subString)

          value += quantity
          pos = roman.index(pos, offsetBy: glyph.count)

          return value




          Now the error handling. Yes, throwing an error is a good and Swifty
          way to report a failure to the caller. (An alternative is to return an
          optional value which is nil in the error case, but that does not
          allow to provide additional error information.)



          The creation of the error message however should be done in the
          error class, by adopting the LocalizedError protocol:



          enum RomanNumericError: Error 
          case badInput(roman: String, at: Substring)


          extension RomanNumericError: LocalizedError
          public var errorDescription: String?
          switch self
          case .badInput(let roman, let at):
          return "Error parsing roman numeral '(roman)' at '(at)'"





          The big advantage is that the caller does not need to know which
          error the function throws, and can catch a generic Error:



          do 
          try print(romanToInt("MMXIV"))
          try print(romanToInt("MMYXIV"))
          catch
          print(error.localizedDescription)


          // Output:
          // 2014
          // Error parsing roman numeral 'MMYXIV' at 'YXIV'





          share|improve this answer























          • Really helpful, thank you. I have trouble using the LocalizedError protocol though; it throws a error: use of undeclared type 'LocalizedError' (Xcode 9.2, in a playground). I'm investigating why, but if you have a clue, I'd be glad to hear it.
            – Christophe Marois
            Jan 26 at 23:29










          • You may need to import Foundation.
            – Martin R
            Jan 26 at 23:33










          • Thanks, your comment and this thread stackoverflow.com/questions/33943477/… clarified the situation.
            – Christophe Marois
            Jan 26 at 23:36












          up vote
          4
          down vote



          accepted







          up vote
          4
          down vote



          accepted






          Let's do this from inside out. temp.starts(with: glyph) is correct, but
          there is also a dedicated method temp.hasPrefix(glyph) for strings.



          The loop to find the first dictionary entry with a matching prefix
          can be shortened to



          guard let (glyph, quantity) = dict.first(where: temp.hasPrefix($0.glyph) ) else 
          throw RomanNumericError.badInput(original: original, temp: temp)



          (also making the var found obsolete.)



          Mutating the temporary string can be avoided by working with a SubString (which is a kind of view into the original string) and
          only updating the current search position:



          var pos = original.startIndex
          while pos != original.endIndex
          let subString = original[pos...]
          // ...
          pos = original.index(pos, offsetBy: glyph.count)



          Naming: This is very opinion-based, here are my opinions:



          • Declare the function as func romanToInt(_ roman: String),
            so that it is called without (external) argument name:
            romanToInt("MMXIV").

          • Rename var int to var value.


          • dict is also a non-descriptive name (and it is not even a dictionary), something like glyphsAndValues might be a better choice.

          Summarizing the suggestions so far, we have



          func romanToInt(_ roman: String) throws -> Int 
          var value = 0
          var pos = roman.startIndex
          while pos != roman.endIndex
          let subString = roman[pos...]
          guard let (glyph, quantity) = glyphsAndValues.first(where: subString.hasPrefix($0.glyph) ) else
          throw RomanNumericError.badInput(roman: roman, at: subString)

          value += quantity
          pos = roman.index(pos, offsetBy: glyph.count)

          return value




          Now the error handling. Yes, throwing an error is a good and Swifty
          way to report a failure to the caller. (An alternative is to return an
          optional value which is nil in the error case, but that does not
          allow to provide additional error information.)



          The creation of the error message however should be done in the
          error class, by adopting the LocalizedError protocol:



          enum RomanNumericError: Error 
          case badInput(roman: String, at: Substring)


          extension RomanNumericError: LocalizedError
          public var errorDescription: String?
          switch self
          case .badInput(let roman, let at):
          return "Error parsing roman numeral '(roman)' at '(at)'"





          The big advantage is that the caller does not need to know which
          error the function throws, and can catch a generic Error:



          do 
          try print(romanToInt("MMXIV"))
          try print(romanToInt("MMYXIV"))
          catch
          print(error.localizedDescription)


          // Output:
          // 2014
          // Error parsing roman numeral 'MMYXIV' at 'YXIV'





          share|improve this answer















          Let's do this from inside out. temp.starts(with: glyph) is correct, but
          there is also a dedicated method temp.hasPrefix(glyph) for strings.



          The loop to find the first dictionary entry with a matching prefix
          can be shortened to



          guard let (glyph, quantity) = dict.first(where: temp.hasPrefix($0.glyph) ) else 
          throw RomanNumericError.badInput(original: original, temp: temp)



          (also making the var found obsolete.)



          Mutating the temporary string can be avoided by working with a SubString (which is a kind of view into the original string) and
          only updating the current search position:



          var pos = original.startIndex
          while pos != original.endIndex
          let subString = original[pos...]
          // ...
          pos = original.index(pos, offsetBy: glyph.count)



          Naming: This is very opinion-based, here are my opinions:



          • Declare the function as func romanToInt(_ roman: String),
            so that it is called without (external) argument name:
            romanToInt("MMXIV").

          • Rename var int to var value.


          • dict is also a non-descriptive name (and it is not even a dictionary), something like glyphsAndValues might be a better choice.

          Summarizing the suggestions so far, we have



          func romanToInt(_ roman: String) throws -> Int 
          var value = 0
          var pos = roman.startIndex
          while pos != roman.endIndex
          let subString = roman[pos...]
          guard let (glyph, quantity) = glyphsAndValues.first(where: subString.hasPrefix($0.glyph) ) else
          throw RomanNumericError.badInput(roman: roman, at: subString)

          value += quantity
          pos = roman.index(pos, offsetBy: glyph.count)

          return value




          Now the error handling. Yes, throwing an error is a good and Swifty
          way to report a failure to the caller. (An alternative is to return an
          optional value which is nil in the error case, but that does not
          allow to provide additional error information.)



          The creation of the error message however should be done in the
          error class, by adopting the LocalizedError protocol:



          enum RomanNumericError: Error 
          case badInput(roman: String, at: Substring)


          extension RomanNumericError: LocalizedError
          public var errorDescription: String?
          switch self
          case .badInput(let roman, let at):
          return "Error parsing roman numeral '(roman)' at '(at)'"





          The big advantage is that the caller does not need to know which
          error the function throws, and can catch a generic Error:



          do 
          try print(romanToInt("MMXIV"))
          try print(romanToInt("MMYXIV"))
          catch
          print(error.localizedDescription)


          // Output:
          // 2014
          // Error parsing roman numeral 'MMYXIV' at 'YXIV'






          share|improve this answer















          share|improve this answer



          share|improve this answer








          edited Jan 26 at 22:24


























          answered Jan 26 at 21:55









          Martin R

          14.1k12257




          14.1k12257











          • Really helpful, thank you. I have trouble using the LocalizedError protocol though; it throws a error: use of undeclared type 'LocalizedError' (Xcode 9.2, in a playground). I'm investigating why, but if you have a clue, I'd be glad to hear it.
            – Christophe Marois
            Jan 26 at 23:29










          • You may need to import Foundation.
            – Martin R
            Jan 26 at 23:33










          • Thanks, your comment and this thread stackoverflow.com/questions/33943477/… clarified the situation.
            – Christophe Marois
            Jan 26 at 23:36
















          • Really helpful, thank you. I have trouble using the LocalizedError protocol though; it throws a error: use of undeclared type 'LocalizedError' (Xcode 9.2, in a playground). I'm investigating why, but if you have a clue, I'd be glad to hear it.
            – Christophe Marois
            Jan 26 at 23:29










          • You may need to import Foundation.
            – Martin R
            Jan 26 at 23:33










          • Thanks, your comment and this thread stackoverflow.com/questions/33943477/… clarified the situation.
            – Christophe Marois
            Jan 26 at 23:36















          Really helpful, thank you. I have trouble using the LocalizedError protocol though; it throws a error: use of undeclared type 'LocalizedError' (Xcode 9.2, in a playground). I'm investigating why, but if you have a clue, I'd be glad to hear it.
          – Christophe Marois
          Jan 26 at 23:29




          Really helpful, thank you. I have trouble using the LocalizedError protocol though; it throws a error: use of undeclared type 'LocalizedError' (Xcode 9.2, in a playground). I'm investigating why, but if you have a clue, I'd be glad to hear it.
          – Christophe Marois
          Jan 26 at 23:29












          You may need to import Foundation.
          – Martin R
          Jan 26 at 23:33




          You may need to import Foundation.
          – Martin R
          Jan 26 at 23:33












          Thanks, your comment and this thread stackoverflow.com/questions/33943477/… clarified the situation.
          – Christophe Marois
          Jan 26 at 23:36




          Thanks, your comment and this thread stackoverflow.com/questions/33943477/… clarified the situation.
          – Christophe Marois
          Jan 26 at 23:36












           

          draft saved


          draft discarded


























           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f186087%2fswift-function-to-interpret-roman-numerals-ported-from-javascript%23new-answer', 'question_page');

          );

          Post as a guest













































































          Popular posts from this blog

          Chat program with C++ and SFML

          Function to Return a JSON Like Objects Using VBA Collections and Arrays

          Will my employers contract hold up in court?