Submission link - https://bigfrontend.dev/problem/78/discuss/928
/**
* @param {string} hex
* @return {string}
*/
function hexToRgba(hex) {
if(!hex.startsWith('#')) throw new Error(); // throw error if input is invalid
const result = [];
// check if 3 hexadecimal digits or
// 4 hexadecimal digits (with alpha value)
// this includes "#" sign too, that's why +1
if(hex.length == 4 || hex.length == 5) {
for(let i = 1; i < hex.length; i++) {
const value = getFunctionalValue(hex[i] + hex[i]);
result.push(value);
}
setAlphaValue(result);
} else if(hex.length == 7 || hex.length == 9) { // either 6 hexadecimal digits value or +2 digits for alpha value
for(let i = 1; i < hex.length - 1; i+=2) {
const value = getFunctionalValue(hex[i] + hex[i+1]);
result.push(value);
}
setAlphaValue(result);
} else {
throw new Error(); // apart from above checks all are invalid inputs
}
function getFunctionalValue(hexPart) { // logic to convert hexadecimal for to integer value
return Number.parseInt(hexPart, 16);
}
function setAlphaValue(result) {
if(result.length < 4) { // 3 digits means no alpha value
result.splice(3, 1, 1); // if no alpha value then set it to 1. (splice(start, removeTill, replacement))
} else {
const value = Number.parseFloat((result[3] / 255).toFixed(2)) // if more than 3 means we need to get fractional value
result.splice(3, 1, value);
}
}
return `rgba(${result.join(',')})`;
}
Again, such problems can be solved by regex or with an iterative approach. As you need to know about conversion rules before you write code, I tried digging online to understand hex to RGB color conversion. I will explain the conversion in the algorithm section and feel free to suggest any kind of optimization in the above code.
There are 4 valid variants of hexadecimal color.
- shorthand (
#fff
) - shorthand with alpha value (
#fff3
) - longhand (
#ffffff
) - longhand with alpha value (
#ffffff33
)
Each pair from left to right represents a red, green, and blue value. If we have shorthand input then we simply add it twice to form a pair. The alpha value works similarly, we either have a pair or single.
This helps us to understand valid input length which is either -
- 3 (for shorthand)
- 4 (for shorthand with alpha value)
- 6 (for longhand)
- 8 (for longhand with alpha value)
If you are not separating #
then you can add +1 in the above length. We are doing the same in our program.
There is two main logic in the above program.
- Conversion of hexadecimal colors
- Conversion of the alpha value
Conversion of hexadecimal colors
- If it is shorthand then we simply add it twice and convert into an integer with base 16
- If it is longhand then we add current and next value and convert into an integer with base 16
Conversion of the alpha value
- The steps are the same as converting to hexadecimal and we do it along with hexadecimal conversion
- We know that we will have either 3 or 4 values in the array. Length 3 implies that there is no alpha value.
- If no alpha value then we add 1
- Else we convert it to fraction/percentage dividing by 255 (maximum color value)
There can be many invalid inputs in the above program.
- We begin with checking if the input starts with the
#
sign. That's how hexadecimal colors are written. If it doesn't then we throw an error. - Next, we create an array
result
to store our RGB values. - For input length validation, we check if the length is either 4 or 5 (this includes
#
sign too)- If this check is valid then we know it is shorthand (with or without alpha value)
- We iterate over input
hex
- We get the value by passing the current value
hex[i]
twice ingetFunctionalValue
that converts it to an integer with base 16 - We push the value in the
result
array
- If the above check fails then we check if the length is either 7 or 9 (this includes
#
sign too)- If this check is valid then we know it is longhand (with or without alpha value)
- We iterate over input
hex
- We get the value by passing the current value
hex[i]
and next valuehex[i+1]
ingetFunctionalValue
which converts it to an integer with base 16 - We increment the index by 2 (
i+=2
) because we already covered the next value in the above step - We push the value in the
result
array
- If this check fails then we consider that input is invalid and we throw an error.
- We also have a
setAlphaValue
function whose job is to convert the alpha value to a fraction. We call this function in each valid case.- As we know that
result
will have either 3 or 4 values. If it is 3 means only RGB is present and we can safely add 1 as alpha value for this case. - If its length is 4 means we need to convert the 3rd
result[3]
position to a fraction. We divide the alpha value by 255 (maximum color value) to get the fraction.
- As we know that
- We form RGBA string at the end and return it
🌻 ✨
I'm excited to improve the solution and code walkthrough. Feel free to drop a comment, or send a PR or send memes @knowkalpesh.