# Roman Numeral Converter - can I use Object instead of arrays?

I have reached an impasse with my code so I took a peek at the Basic Solution to see how far off I was. The most glaring difference was that the Basic Solution uses 2 separate arrays (of decimals and their corresponding roman numerals) and my solution is going to use an object:

`var numConvertor = {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'};`

I am running into many issues which essentially require me to convert to arrays. That is, at some point, I will have to have an array of the properties (of my object, `numConvertor`) that I can compare against. As per this Q&A, I can do that but then I will end up with an array of strings not numbers. Which seems like I am not only moving towards the Basic Solution approach (i.e. arrays) but moving even further backwards b/c I end up with an array of string which I then have to convert to numbers in order to compare and convert…?

Is there any point in trying to salvage a solution that uses object instead of arrays?

And if so, is what I outlined above the correct course of action?

Thank you!

``````function convertToRoman(num) {
//create object of decimal to roman key/values
var numConvertor = {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'};

//break decimal number into array of units
function numBreakdown(n) {
if (n == 0) return ;
var arr = [];
var i = 1;

while (n > 0) {
arr.unshift((n % 10) * i);
n = Math.floor(n / 10);
i *= 10;
};
return arr;
}

let arrNumBreakdown = numBreakdown(num);

//go through array and convert each to a roman numeral based on numConvertor object

for(var i = 0; i < arrNumBreakdown.length; i++){
//is there a way to check value of property to compare which is the largest number that is smaller than numBreakdown[i]?
//Or do I HAVE to use the array methodology as per Basic Solution?
}

//combine results from each iteration into one string value?
}

//convertToRoman(36);

``````

The downside to using an object to maintain that list is, you have no control over the order you’ll get the properties. If, for example, you use `let keys = Object.keys(numConvertor)` to get the numeric values you use as indexes (indices?) within `numConvertor`, then simply do something like `numConvertor[keys[i]] to get the appropriate string value, you have no way of knowing if your FIRST value is 1 or 1000.

Arrays are the best way of getting the data in a consistent manner.

1 Like

That said, I took your `numConvertor` object idea, and tinkered with it a little. If you simply sort the keys in reverse order (greatest to least), then use THAT array (for example, `keys = 1000`) to get the object value (in the previous, `numConvertor[keys] = numConvertor = "M"` ), then you could get that to work nicely.

Of course, that COMPLETELY changes the way you’re parsing through the original `num` value…

So I went with arrays after all.

And even though I had sneaked a peek at the Basic Solution, I wanted to work through the code without referring to it again. And it ain’t pretty.

First, I gave myself a huge advantage by adding more to the `decimals` and `romans` arrays so that more numbers would simply be converted. But I stuck to the basic combinations that were listed here >>> link.

Having done that, I made some Frankenstein-ish code But I continue to get stymied by anything higher than 1000.

Any ideas how I can fix this? Obviously, I cannot keep adding to the `decimals`/`romans` arrays.

Specifically failing these 2 test-cases right now:

``````convertToRoman(2014)
convertToRoman(3999)
``````

So the logic should go like this:

• starting from the largest value, 1000 in this case, is the number divisible by the value one or more time?
• if so, do two things – append that many of the appropriate letter, and set num to (num - that many units). Aconvenient shortcut here would be the modulo operator, %.
• keep moving to the next smaller value repeating those steps until num equals zero.

Is that the gist of what you’re doing?

Here’s a link to your object approach in action. Open the console to see it work. https://codepen.io/snowmonkey/pen/qLZwdv?editors=0011

So I decided to start from scratch again. My old code was confusing me more than helping me.

I’ve done several more iterations of code and I keep getting stuck. But let me go back to your rules and ask a question that I tried to answer on my own and is probably what led me down the wrong path.

How can I use % to check how many times a number is divisible by another number? Since % will only return the remainder and not the quotient (which is really what I want isn’t it…?)

So instead of using % (and this might be where I went wrong), I checked for divisibility like this:

`let numDivisible = Math.floor(num / decimals[i]);`

Is that wrong?

This is my incomplete code so far, in case:

``````function convertToRoman(num) {
//create object of decimal to roman key/values
let decimals = [1000,900,800,700,600,500,400,300,200,100,90,80,70,60,50,40,30,20,10,9,8,7,6,5,4,3,2,1];
let romans = ['M','CM','DCCC','DCC','DC','D','CD','CCC','CC','C','XC','LXXX','LXX','LX','L','XL','XXX','XX','X','IX','VIII','VII','VI','V','IV','III','II','I',];

let resultRomans = "";

for(var i = 0; i < decimals.length; i++){
//starting from the largest value, 1000 in this case, is the number divisible by the value one or more time?
let numDivisible = Math.floor(num / decimals[i]);
console.log(numDivisible);
if(numDivisible > 1){
console.log(romans[i]);
resultRomans += romans[i];
console.log("This is num - decimals[i]: " + (num - decimals[i]));
num -= decimals[i]
}else {
return romans[decimals.indexOf(num)];
}
//if so, do two things – append that many of the appropriate letter, and set num to (num - that many units).
//Aconvenient shortcut here would be the modulo operator, %.
//keep moving to the next smaller value repeating those steps until num equals zero.
}
}
``````

Final code:

[spoiler]```

function convertToRoman(num) {
//create object of decimal to roman key/values

let decimals = [1000,900,800,700,600,500,400,300,200,100,90,80,70,60,50,40,30,20,10,9,8,7,6,5,4,3,2,1];
let romans = [‘M’,‘CM’,‘DCCC’,‘DCC’,‘DC’,‘D’,‘CD’,‘CCC’,‘CC’,‘C’,‘XC’,‘LXXX’,‘LXX’,‘LX’,‘L’,‘XL’,‘XXX’,‘XX’,‘X’,‘IX’,‘VIII’,‘VII’,‘VI’,‘V’,‘IV’,‘III’,‘II’,‘I’,];

let resultRomans = “”;

for(var i = 0; i < decimals.length; i++){
while (decimals[i] <= num) {
resultRomans += romans[i];
num -= decimals[i];
}
}
return resultRomans;
}

Have you tested that with other numbers? Like 2018 or 4321?

You were on the right track with `numDivisible`. That tells you, for example, that 4321 is divisible by 1000 four times. Then setting `num = num %1000` (num “modulo” 1000) makes `num = 321`. Now, how do you repeat the ‘M’ numDivisible times?

I could have avoided using % by setting

``````num = num - (numDivisible * decimals[i] );
``````

But the result is the same.