## Roman Numerals in Javascript

I was looking at some code that included converting arabic to roman numerals, and it was all things like this:

``````
function Level(i, v, x)
{
this.i = i;
this.v = v;
this.x = x
}

levels = new Array();

levels[0] = new Level('I', 'V', 'X');
levels[1] = new Level('X', 'L', 'C');
levels[2] = new Level('C', 'D', 'M');

function calcDigit(d, l)
{
if (l > 2)
{
str = '';
for (var m = 1; m <= d * Math.pow(10, l - 3) ; m++)
str += 'M';
return str
}

else
if (d == 1)
return levels[l].i
else
if (d == 2)
return levels[l].i + levels[l].i
else
if (d == 3)
return levels[l].i + levels[l].i + levels[l].i
else
if (d == 4)
return levels[l].i + levels[l].v
else
if (d == 5)
return levels[l].v
else
if (d == 6)
return levels[l].v + levels[l].i
else
if (d == 7)
return levels[l].v + levels[l].i + levels[l].i
else
if (d == 8)
return levels[l].v + levels[l].i + levels[l].i + levels[l].i
else
if (d == 9)
return levels[l].i + levels[l].x
else
return ''
// And so on
``````

It all reminded me of fourth-grade BASIC. I should have been taking care of patients, but the challenge of writing a better converter kept me busy for a few minutes. Here's what I came up with:

``````
var romanNumerals = [
[1000, 'M'],
[900, 'CM'],
[500, 'D'],
[400, 'CD'],
[100, 'C'],
[90, 'XC'],
[50, 'L'],
[40, 'XL'],
[10, 'X'],
[9, 'IX'],
[5, 'V'],
[4, 'IV'],
[1, 'I']
];
arabic2roman = function(n){
var r = '';
for (var i = 0; i < romanNumerals.length; ++i){
for (var x = romanNumerals[i]; n >= x[0]; n -= x[0]) r += x[1];
}
return r;
}
roman2arabic = function(r){
var n = 0;
for (var i = 0; i < romanNumerals.length; ++i){
for (var x = romanNumerals[i], l = x[1].length; r.substr(0,l) == x[1]; r = r.substr(l)) n += x[0];
}
return n;
}
``````

Or, if you are willing to assume that your browser will always enumerate objects in order, you can make it a bit smaller:

``````
var romanNumerals = { // assumes objects are enumerated in order
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
};
arabic2roman = function(n){
var r = '';
for (var x in romanNumerals){
for (var i = romanNumerals[x]; n >= i; n -= i) r += x;
}
return r;
}
roman2arabic = function(r){
var n = 0, i = 0;
for (var x in romanNumerals){
for (var l = x.length; r.substr(i,l) == x; i+=l) n += romanNumerals[x];
}
return n;
}
``````

Anyone out there with something smaller?