Ok here is my approach. I have broken it down into functions.
Helper function:
So the first function is a helper function to truncate numbers to a given number of decimal places. The toFixed method I used yesterday rounds numbers up and we don’t want that.
const trunc = (num, places = 1) => {
// using the RexExp constructor to dynamically create a regex
// so places = 2 -> regex = \d+\.\d{1,2}
const regex = new RegExp(`\\d+\\.\\d{1,${places}}`)
const match = num.match(regex)
return (match !== null) ? match[0] : null
}
console.log(trunc('861.44 7', 1)) // 861.4
console.log(trunc('861.4563', 2)) // 861.45
console.log(trunc('861.42', 5)) // 861.42
Truncate group methods:
Secondly I have grouped the functions/methods we want to call into an object.
const truncate = {
first: (code) => {
// we can split a string using a regex
// / ([A-Z]{2})/ splits code on a space followed by
// 2 letters and captures those letters e.g.
// 861.44 CU -> ['861.44', 'CU']
// 861.44 7 -> ['861.44 7']
const [num, letters] = code.split(/ ([A-Z]{2})/)
// truncate number to 1 decimal place
const truncNumber = trunc(num, 1)
// if letters exist?
return (letters)
? `${truncNumber} ${letters}` // true: return with letters
: `${truncNumber}` // false: return without
},
second: (code) => parseInt(code, 10), // return integer (may need to fix this)
third: (code) => trunc(code, 2) // return to 2 decimal places
}
We will be able to call them by name e.g. truncate.third(‘12.234’) → ‘12.23’
Group matches:
Next I have grouped the matches into an object. Note the key names, first, second etc correspond with the truncate functions we want to call if that match is found.
const groupMatches = {
first: /8[4-6][0-9].*/, // e.g. if match will call truncate.first(code)
second: /80[1-7]/,
third: /839.3[16]*/
}
formatCode function:
Finally the formatCode function. This will loop through the groupMatches checking them against the given code and will call the corresponding truncate function returning a value.
// I would prefer to pass in groupMatches as an argument,
// but trying to keep it simple
const formatCode = (code) => {
// loop through groupMatches separating key and value into
// groupName and regex e.g. ['first', /8[4-6][0-9].*/]
for (const [groupName, regex] of Object.entries(groupMatches)) {
// test the regex against the code
if (regex.test(code)) {
// if a match, check to see if truncate has a matching groupName
// e.g. first, second, third
if (Object.hasOwn(truncate, groupName)) {
// if it does call that method and return the truncated code
return truncate[groupName](code)
}
}
}
}
We haven’t handled non matches, but it is a start.
Check console for outputs.