Roman Numeral converter optimization

Hi! I managed to finish this project yesterday after having a short dream on how to lol. I’m wondering if there’s a better way than using a bunch of for loops and arrays to do this, such as forEach, idk. I’m really happy it works but I’m confident there’s a better approach.

Here’s the whole thing in codePen: https://codepen.io/Ignacio-Fenelli/pen/bGZPoMN

Here’s just the JS script:

Summary
const numberInput = document.getElementById("number");
const convertButton = document.getElementById("convert-btn");
const output = document.getElementById("output");



function convertRom () {

  const numbersList = numberInput.value.split((/(\d)/)).filter(Boolean)
  for (let i = numbersList.length; numbersList.length < 4; i--) {
    numbersList.unshift('0');
    i -= 1
  }

  
  console.log("numbersList " + numbersList);
  const romanDigit1 = [];
  const romanDigit2 = [];
  const romanDigit3 = [];
  const romanDigit4 = [];

  for (let digit1 = numbersList[0]; digit1 > 0; digit1 -1){
    romanDigit1.push("M");
    digit1 -= 1
  }

  for (let digit2 = Number(numbersList[1]); digit2 > 0; digit2 === digit2){

      if (digit2 === 9) {
        romanDigit2.push("CM")
        digit2 -= 9;
      } else if (digit2 === 5){
        romanDigit2.unshift("D")
        digit2 -= 5;
      } else if (digit2 === 4){
        romanDigit2.push("CD")
        digit2 -= 4;
      } else {
        romanDigit2.push("C");
        digit2 -= 1 
      }
  } 

  for (let digit3 = Number(numbersList[2]); digit3 > 0; digit3 === digit3){

      if (digit3 === 9) {
        romanDigit3.push("XC")
        digit3 -= 9;
      } else if (digit3 === 5){
        romanDigit3.unshift("L")
        digit3 -= 5;
      } else if (digit3 === 4){
        romanDigit3.push("XL")
        digit3 -= 4;
      } else {
        romanDigit3.push("X");
        digit3 -= 1 
      }
  } 

  for (let digit4 = Number(numbersList[3]); digit4 > 0; digit4 === digit4){
    
      if (digit4 === 9) {
        romanDigit4.push("IX")
        digit4 -= 9;
      } else if (digit4 === 5){
        romanDigit4.unshift("V")
        digit4 -= 5;
      } else if (digit4 === 4){
        romanDigit4.push("IV")
        digit4 -= 4;
      } else {
        romanDigit4.push("I");
        digit4 -= 1 
      }    

  }
  
  const romanResult = romanDigit1.join("") + romanDigit2.join("") + romanDigit3.join("") + romanDigit4.join("");
  output.innerHTML = romanResult;
}



function validate() {
  switch (true){
    case numberInput.value === "":
      output.innerHTML = "Please enter a valid number";
      numberInput.value = "";
      break
    case numberInput.value <= 0:
      output.innerHTML = "Please enter a number greater than or equal to 1";
      numberInput.value = "";
      break
    case numberInput.value >= 4000:
      output.innerHTML = "Please enter a number less than or equal to 3999";
      numberInput.value = "";
      break
      default:
        convertRom();
  }
}


convertButton.addEventListener("click", validate)

I used a few arrays to list the nine possibilities for each Arabic numeral digit, then built the roman numeral from those arrays. No loops involved. It’s about a third the length of your solution. If that’s interesting to you, here’s the Javascript:

const number = document.getElementById("number");
const convertBtn = document.getElementById("convert-btn");
const output = document.getElementById("output");

const oneArray = ["", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"]
const tenArray = ["", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"]
const hundredArray = ["", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"]
const thousandArray = ["", "M", "MM", "MMM"]

const formSubmit = () => {
    
    const formValue = number.value;
    let outcome = "";

    function outputMessage(inputText) {
        output.innerText = inputText;
    }

    let thousands = Math.floor(formValue / 1000) // 0, 1, 2, 3
    let hundreds = Math.floor((formValue % 1000) / 100) // 0, 1, 2, 3 ... 9
    let tens = Math.floor((formValue % 100) / 10) // 0, 1, 2, 3 ... 9
    let ones = Math.floor(formValue % 10) // 0, 1, 2, 3 ... 9

    let final = thousandArray[thousands] + hundredArray[hundreds] + tenArray[tens] + oneArray[ones];

    if (formValue === "") {
        outputMessage("Please enter a valid number"); 
    } else if (formValue < 1) {
        outputMessage("Please enter a number greater than or equal to 1");
    } else if (formValue > 3999) {
        outputMessage("Please enter a number less than or equal to 3999");
    } else {
        outputMessage(final);
    }
}

convertBtn.addEventListener("click", formSubmit)```

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.