Taking a closer look at the question, it can be divided into three steps:

  • fromrgb(255, 255, 255)extractr=255g=255b=255
  • willrgbConvert to hexadecimal, fill zero if there are less than two digits
  • combination#

Extract r, G and B

Method 1: Use match

Use match() to read r, g, b

function rgb2hex(sRGB) {
    const reg = RGB | / ^ (RGB) \ [\ s * (\ d {1, 3}) \ s * \ s * (\ d {1, 3} \ s *), \ s * (\ d {1, 3}) \ \ s *) $/
	const rbg = sRGB.match(reg)
    return rbg
}

/ / test
rgb2hex('rgb(255, 255, 255)')
// ["rgb(255, 255, 255)", "rgb", "255", "255", "255", index: 0, input: "rgb(255, 255, 255)", groups: undefined]
rgb2hex('rgb(16, 10, 255)')
// ["rgb(16, 10, 255)", "rgb", "16", "10", "255", index: 0, input: "rgb(16, 10, 255)", groups: undefined]
Copy the code

R = RGB [2], g = RGB [3], b = RGB [4]

Method two: usematch()Method (2)

RGB (255, 255, 255) r, G, b are consecutive digits, so we can use the regular /\d+/g to get all the consecutive digits

function rgb2hex(sRGB) {
    const rgb = sRGB.match(/\d+/g);
    return rgb
}

/ / test
rgb2hex('rgb(255, 255, 255)')
/ / / "255", "255", "255"]
rgb2hex('rgb(16, 10, 255)')
/ / / "16", "10", "255"]
Copy the code

Replace + use split

Observe that each color value of RGB (255, 255, 255) is joined together by, so we consider whether we can split each color value by split(‘,’). We mainly consider two steps

  • replacergb(255, 255, 255)Partial characters of (rgb()) for' '
  • Separate out each color value
function rgb2hex(sRGB) {
    const rgb = sRGB.replace(/ (? :\(|\)|rgb|RGB)*/g.' ').split(', ')
    return rgb
}
/ / test
rgb2hex('rgb(255, 255, 255)')
// ["255", "255", "255"]
rgb2hex('rgb(16, 10, 255)')
// ["16", "10"," 255"]
Copy the code

Conversion to hexadecimal, not enough to complement zeros

Convert to hexadecimal, which can be:

  • (+n).toString(16)Number(n).toString(16) `

If less than two, fill zero:

  • ('0' + r16).slice(-2)

  • r16.padStart(2, '0')

  • (r < 16? '0':'') + r16

  • r16.length < 2 ? '0' + r16 : r16

  • ((1 << 24) + (Number(r) << 16) + (Number(g) << 8) + Number(b)).toString(16).slice(1)

Various ways, divergent thinking, 🤔 more

combination#

reduce

Note that the output can be uppercase (#FFFFFF) or lowercase (#FFFFFF), in this case uppercase

rgb.reduce((acc, cur) = > acc + hex, The '#').toUpperCase()
Copy the code

+

It can also be connected by +, as the case may be

Various ways, divergent thinking, 🤔 more

conclusion

The question is divided into the above three steps, choose a combination of each step to achieve the question, the final implementation of a variety of schemes, simple here list some of the combination

A combination of

function rgb2hex(sRGB) {
    var rgb = sRGB.replace(/ (? :\(|\)|rgb|RGB)*/g.' ').split(', ')
    return rgb.reduce((acc, cur) = > {
        var hex = (cur < 16? '0':' ') + Number(cur).toString(16)
        return acc + hex
    }, The '#').toUpperCase()
}

/ / test
rgb2hex('rgb(255, 255, 255)')
// "#FFFFFF"
rgb2hex('rgb(16, 10, 255)')
// "#100AFF"
Copy the code

Combination of two

function rgb2hex(rgb) {
    const rgb = rgb.match(/\d+/g);
    const hex = (n) = > {
        return ("0" + Number(n).toString(16)).slice(-2);
    }
    return rgb.reduce((acc, cur) = > acc + hex, The '#').toUpperCase()
}

/ / test
rgb2hex('rgb(255, 255, 255)')
// "#FFFFFF"
rgb2hex('rgb(16, 10, 255)')
// "#100AFF"
Copy the code

The combination of three

function rgb2hex(sRGB) {
    const rgb = sRGB.replace(/ (? :\(|\)|rgb|RGB)*/g.' ').split(', ')
    return "#" + ((1 << 24) + (Number(rgb[0]) < <16) + (Number(rgb[1]) < <8) + Number(rgb[2])).toString(16).slice(1).toUpperCase()
}

/ / test
rgb2hex('rgb(255, 255, 255)')
// "#FFFFFF"
rgb2hex('rgb(16, 10, 255)')
// "#100AFF"
rgb2hex('rgb(1, 2, 3)')
/ / "# 010203"
Copy the code

Three minutes a day