Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

实现颜色转换 'rgb(255, 255, 255)' -> '#FFFFFF' 的多种思路 #89

Open
sisterAn opened this issue Apr 20, 2021 · 0 comments
Open

Comments

@sisterAn
Copy link
Owner

sisterAn commented Apr 20, 2021

仔细观察本题,本题可分为三个步骤:

  • rgb(255, 255, 255) 中提取出 r=255g=255b=255
  • rgb 转换为十六进制,不足两位则补零
  • 组合 #

提取 r、g、b

方式一:利用 match

利用 match() 方法,读取出 rgb

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
}

// 测试
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]

r = rgb[2]g = rgb[3]b = rgb[4]

方式二:利用 match() 方法(2)

rgb(255, 255, 255)rgb 分别为连续的数字,所以我们可以利用正则 /\d+/g 获取取所有连着的数字

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

// 测试
rgb2hex('rgb(255, 255, 255)')
// ["255", "255", "255"]
rgb2hex('rgb(16, 10, 255)')
// ["16", "10", "255"]

方式三:replace + 利用 split

观察 rgb(255, 255, 255) 的每一个色值是透过 , 连接一起的,所以我们考虑是否能通过 split(',') 拆分出每一个色值,主要考虑两步

  • 替换 rgb(255, 255, 255) 的部分字符( rgb() )为 ''
  • 拆分出每一个色值
function rgb2hex(sRGB) {
    const rgb = sRGB.replace(/(?:\(|\)|rgb|RGB)*/g, '').split(',')
    return rgb
}
// 测试
rgb2hex('rgb(255, 255, 255)')
// ["255", " 255", " 255"]
rgb2hex('rgb(16, 10, 255)')
// ["16", " 10", " 255"]

转换为十六进制,不足补零

转换为十六进制,可采用:

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

不足两位则补零:

  • ('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)

方式多种多样,发散思维,🤔更多

组合 #

reduce

注意,输出为可为大写( #FFFFFF )或小写字符( #ffffff ),本题为大写

rgb.reduce((acc, cur) => acc + hex, '#').toUpperCase()

+

也可以通过 + 连接,按情况而定

方式多种多样,发散思维,🤔更多

总结

把本题拆分成以上三步,选取每步的一种实现方式组合实现本题,最终实现方案多种多样,简单这里列一下 其中的部分组合

组合一

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
    }, '#').toUpperCase()
}

// 测试
rgb2hex('rgb(255, 255, 255)')
// "#FFFFFF"
rgb2hex('rgb(16, 10, 255)')
// "#100AFF"

组合二

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, '#').toUpperCase()
}

// 测试
rgb2hex('rgb(255, 255, 255)')
// "#FFFFFF"
rgb2hex('rgb(16, 10, 255)')
// "#100AFF"

组合三

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()
}

// 测试
rgb2hex('rgb(255, 255, 255)')
// "#FFFFFF"
rgb2hex('rgb(16, 10, 255)')
// "#100AFF"
rgb2hex('rgb(1, 2, 3)')
// "#010203"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant