Convert a Number into a Roman Numeral in JavaScript

convert number into roman numerals

The problem with your code:

You are starting with the first index

for (var i=0 ; i<arrayLen ; i++)

so?

Object.keys(lookupObj)[i]

This happens and that gives 1

Because objects with numeric keys get sorted in ascending order of the numbers.


Result of: Object.keys(lookupObj)

Object.keys(lookupObj)
// ["1", "4", "5", "9", "10", "40", "50", "90", "100", "400", "500", "900", "1000"]

Object.keys(): The order of keys:

  1. Numeric keys are sorted first (even if other keys are present) in ascending order.
  2. String keys are sorted in the order of their creation.
  3. Lastly, Symbols get sorted in the order of their creation

Had your object been anything like:

var lookupObj = {
1000:"M",
Z: 'is the last alphabet',
Apples: 'keep the doctors away',
900:"CM",
500:"D",
400:"CD",
100:"C",
90:"XC",
50:"L",
40:"XL",
10:"X",
9:"IX",
4:"IV",
5:"V",
1:"I",
};

The result for this would have been

["1", "4", "5", "9", "10", "40", "50", "90", "100", "400", "500", "900", "1000", "Z", "Apples"]

PS: I haven't used iterables, but I am aware that they too impact key ordering. I'll add a link here.


Other points as mentioned to you in comments:

var arrayLen = Object.keys(lookupObj).length; // [1]

while(num>0){
for (var i=0 ; i<arrayLen ; i++) {
if(num >= Object.keys(lookupObj)[i]) { // [2]
roman = roman + lookupObj[Object.keys(lookupObj)[i]]; // [3]
num = num - Object.keys(lookupObj)[i]; // [4]
break;
}
}
}

You are calling the same function 4 times, you could save the value in a variable.

var lookupAsArray = Object.keys(lookupObj)

while(num>0) {
for (var i=0 ; i< lookupAsArray; i++) { // This line is optimised by browsers
if(num >= lookupAsArray[i]) { // so is faster than it seems
roman = roman + lookupObj[lookupAsArray[i]];
num = num - lookupAsArray[i];
break;
}
}
}

convert roman numerals using for loop

The second for loop is a bit weird, you don't use j for anything.

You can replace that and the if inside with a simpler while loop.

//values of the numbers
let numerals = {
M: 1000,
CM: 900,
D: 500,
CD: 400,
C: 100,
XC: 90,
L: 50,
XL: 40,
X: 10,
IX: 9,
V: 5,
IV: 4,
I: 1,
};

const convertToRoman = (num) => {
let newNumeral = "";

for (let i in numerals) {
while (num >= numerals[i]) {
newNumeral += i;
num -= numerals[i];
}
}

return newNumeral;
}

console.log(convertToRoman(3));
console.log(convertToRoman(1990));

javascript algorithm converting to roman numbers

The @Nina Scholz answer is the correct (and also, elegant), but note that you have trouble with the zeros (actually, like Romans had!).

If you want your code to work, you have to add the zero to the conversion array, the first think would be just add {0:''} but then, as empty string, the filter function will fail, so you can add a space for the key '0', and finally, apply a trim the result.

Something like this:

function convertToRoman(num) {
//TABLE OF EQUIVALENCES
var arrConv=[{0:' '},{1:'I'},{2:'II'},{3:'III'},{4:'IV'},{5:'V'},{6:'VI'},{7:'VII'},{8:'VIII'},{9:'IX'},{10:'X'},{20:'XX'},{30:'XXX'},{40:'XL'},{50:'L'},{60:'LX'},{70:'LXX'},{80:'LXXX'},{90:'XC'},{100:'C'},{200:'CC'},{300:'CCC'},{400:'CD'},{500:'D'},{600:'DC'},{700:'DCC'},{800:'DCCC'},{900:'CM'},{1000:'M'},{2000:'MM'},{3000:'MMM'},{4000:'MMMM'},{5000:'MMMMM'},{6000:'MMMMMM'},{7000:'MMMMMMM'},{8000:'MMMMMMMM'},{9000:'MMMMMMMMM'}];

//First we break down the number into its units
//and create an array ex: 652 ==> [600, 50, 2]
var arr=[num.length];
arr=num.toString().split("").reverse();
var i=1;
for (var k=0;k<arr.length;k++){
arr.splice(k,1,arr[k]*i);
i*=10;
}

//We make an array of objects with the number and the roman number equivalence
var romansArray=[];
for (i=0;i<arr.length;i++){
var val=arrConv.filter(function(obj){
return obj[arr[i]];
})[0];
romansArray.push(val);
}

//I get rid of all the null values
var result=romansArray.filter(function(val){
return (val!=null);
});

//It returns the string with the roman number
return result.map(function(value,key){
return result[key][arr[key]];
}).reverse().join("").trim();

}

Anyway, as I said, the Nina's answer is the good one.

Roman Numeral to Number Conversion in Javascript/HTML

You just have some syntax errors.

You're missing an ending ) in number = getValue(romNum.charAt(1) - getValue(romNum.charAt(0));

Also in most of your getElementById() elements you're missing quotes around your ids. And you need to change your variable ronNum to romNum in your else block.

Fixing those seemed get some of your functionality to work. You would just need to work on your Reset Button functionality now. Hopefully this helps.

<html><head>    <title>Roman Numeral Converter</title></head><body><div>     <p id="countdown"></p>    <p id="time"></p>    <p> Please enter a Roman number (e.g. LIV) to convert to a number: </p>    <form action="PayslipServlet" method="get">        <input type="text" name="romannumber" id="rn"> => <span id="result"></span>        <br>        <input type="button" value="Convert" onClick="toNumber()"> <input type="button" value="Reset" onclick="empty()">    </form></div><script type="text/javascript">
function sbCountdown() {
var countdownDate = new Date("February 2, 2020").getTime();
var now = new Date(); var rn = now.getTime();
var daysLeft = countdownDate - rn;
var days = Math.floor(daysLeft / (1000 * 60 * 60 * 24));
document.getElementById("countdown").innerHTML = "There are " + days + " days until SUPER BOWL LIV 2020 (February 2, 2020)";
if(daysLeft < 0) { document.getElementById('countdown').innerHTML = "EXPIRED"; }
setTimeout(sbCountdown, 1000); }
sbCountdown();

function updateClock() {
var now = new Date(), // current date months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']; var dateString = "*** The Current Time is: "; var hh = now.getHours(); var dd = "AM"; var h = hh; if(h >= 12 ) { h = hh - 12; dd = "PM"; } if( h == 0 ) { h = 12; } time = h + ':' + now.getMinutes() + ':' + now.getSeconds() + " " + dd;
// a cleaner way than string concatenation date = [now.getDate(), months[now.getMonth()], now.getFullYear()].join(' ');
// set the content of the element with the ID time to the formatted string document.getElementById('time').innerHTML = dateString + date + " , " + time;
// call this function again in 1000ms setTimeout(updateClock, 1000); }
updateClock();

function getValue(s) {
var num = 0;
if(s == 'I') { num = 1 } else if(s == 'V') { num = 5 } else if(s == 'X') { num = 10 } else if(s == 'L') { num = 50 } else if(s == 'C') { num = 100 } else if(s == 'D') { num = 500 } else if(s == 'M') { num = 1000 } else { document.getElementById('result').innerHTML = "Not a Roman Numeral" }
return num; }
function toNumber() {
var total = 0; var romNum = document.getElementById('rn').value var number;

while(romNum != "") {
if(getValue(romNum.charAt(0)) >= getValue(romNum.charAt(1)) || romNum.length == 1) {
number = getValue(romNum.charAt(0)); total += number;
var temp = romNum.slice(1); romNum = temp; } else {
number = getValue(romNum.charAt(1)) - getValue(romNum.charAt(0)); total += number;
var temp = romNum.slice(2); romNum = temp; }
}
document.getElementById('result').innerHTML = total; }

</script>
</body></html>


Related Topics



Leave a reply



Submit