Reputation: 494
I have a function in javascript where the schoolClass
it's an roman number like this I
, II
, IV
etc. this function is called multiple times and the result it's concatenated in an array like this:
const generateClasses = (schoolClass, number) => {
const classes = [];
for (let i = 0; i < number; i++) {
classes.push(`${schoolClass}-${(i + 10).toString(36).toUpperCase()}`);
}
return classes;
};
let output = [];
output = output.concat(generateClasses('II', 2));
output = output.concat(generateClasses('I', 1));
output = output.concat(generateClasses('IV', 2));
console.log(output);
in the end the output it's like this:
["II-A", "II-B", "I-A", "IV-A", "IV-B"]
how to order the array-like ["I-A", "II-A", "II-B", "IV-A", "IV-V"]
I appreciate any help!
PS: for converting numbers in roman I use the roman-numbers
module
Upvotes: 0
Views: 737
Reputation: 350345
As school grades are limited to 12, the alphabetical sort isn't that bad to start with. For the example you have given you could just call .sort()
on that array and it would be fine.
Actually, only "IX" would get sorted at the wrong place. So let's deal with that:
let classes = ["XII-A", "IX-A", "VII-A", "II-A", "II-B", "I-A", "IV-A", "IV-B"];
let trans = s => s.replace("IX", "VIIJ");
classes.sort((a, b) => trans(a).localeCompare(trans(b)));
console.log(classes);
This would work for Roman numbers that don't use any other symbols than I, V and X, so up to 39.
Upvotes: 2
Reputation: 986
Here I converted the Roman to Integer by iterating each Roman character So XII will be (10+1+1)
Now Sort them but if 2 Roman character are same than I compare the Alphabet attached with it.
const num = ["II-B", "II-A", "I-A", "IV-A", "IV-B"];
num.sort((a, b) => {
const diff = roman_to_Int(a.split("-")[0]) - roman_to_Int(b.split('-')[0]);
if (diff === 0) {
return a.split("-")[1].localeCompare(b.split("-")[1]);
}
return diff;
});
console.log(num);
/* Source - https://www.w3resource.com/javascript-exercises/javascript-math-exercise-22.php */
function roman_to_Int(str1) {
if(str1 == null) return -1;
var num = char_to_int(str1.charAt(0));
var pre, curr;
for(var i = 1; i < str1.length; i++){
curr = char_to_int(str1.charAt(i));
pre = char_to_int(str1.charAt(i-1));
if(curr <= pre){
num += curr;
} else {
num = num - pre*2 + curr;
}
}
return num;
}
function char_to_int(c){
switch (c){
case 'I': return 1;
case 'V': return 5;
case 'X': return 10;
case 'L': return 50;
case 'C': return 100;
case 'D': return 500;
case 'M': return 1000;
default: return -1;
}
}
Upvotes: 0
Reputation: 29032
You need to convert the Roman numeral to a normal (Arabic) one to compare. Since you have very constrained amount of Roman numerals, the easiest way is to just hardcode them - no need to involve an algorithm that transforms them if you only have 12 different possible inputs.
With hardcoded values for I to XII, you can sort based on multiple criteria by splitting your string on -
and:
const romanTable = {
"I" : 1,
"II" : 2,
"III" : 3,
"IV" : 4,
"V" : 5,
"VI" : 6,
"VII" : 7,
"VIII": 8,
"IX" : 9,
"X" : 10,
"XI" : 11,
"XII" : 12,
};
const arr = ["II-A", "II-B", "I-A", "IV-A", "IV-B"];
arr.sort((a, b) => {
const [mainA, secondaryA] = a.split("-");
const [mainB, secondaryB] = b.split("-");
if (mainA !== mainB)
return romanTable[mainA] - romanTable[mainB];
return secondaryA.localeCompare(secondaryB);
});
console.log(arr);
Upvotes: 2