首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >根据十六进制颜色获取最接近的颜色名称

根据十六进制颜色获取最接近的颜色名称
EN

Stack Overflow用户
提问于 2013-06-19 01:53:23
回答 1查看 4.5K关注 0票数 9

我尝试根据给定的十六进制值获得最匹配的颜色名称。例如,如果我们有一个十六进制的颜色名,我们必须得到#f00red

代码语言:javascript
复制
'#ff0000' => 'red'
'#000000' => 'black'
'#ffff00' => 'yellow'

我目前使用levenshtein-distance算法来获得最接近的颜色名称,到目前为止工作得很好,但有时并不像预期的那样。

例如:

代码语言:javascript
复制
'#0769ad' => 'chocolate'
'#00aaee' => 'mediumspringgreen'

那么,有没有办法让结果更接近呢?

这是我为获得最接近的颜色所做的:

代码语言:javascript
复制
Array.closest = (function () {

    // http://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Levenshtein_distance#JavaScript
    function levDist(s, t) {
        if (!s.length) return t.length;
        if (!t.length) return s.length;

        return Math.min(
            levDist(s.substring(1), t) + 1,
            levDist(t.substring(1), s) + 1,
            levDist(s.substring(1), t.substring(1)) + (s[0] !== t[0] ? 1 : 0)
        );
    }

    return function (arr, str) {
        // http://stackoverflow.com/q/11919065/1250044#comment16113902_11919065
        return arr.sort(function (a, b) {
            return levDist(a, str) - levDist(b, str);
        });
    };

}());

http://jsfiddle.net/ARTsinn/JUZVd/2/

另一件事是性能!看起来这里有一个非常大的问题,使得它非常慢(是算法吗?)。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-06-19 02:19:10

Levenshtein距离在这里并不是很合适,因为它将逐个字符地比较是否相等。您需要分别检查每种颜色,并且您可能希望7900更接近80

下面的代码看起来更接近你想要的,只需要对你的代码做最少的修改:

代码语言:javascript
复制
Array.closest = (function () {
    function dist(s, t) {
        if (!s.length || !t.length) return 0;
        return dist(s.slice(2), t.slice(2)) +
            Math.abs(parseInt(s.slice(0, 2), 16) - parseInt(t.slice(0, 2), 16));
    }

    return function (arr, str) {
        return arr.sort(function (a, b) {
            return dist(a, str) - dist(b, str);
        });
    };
}());

请注意,只有当st都是6个字符的十六进制颜色代码时,这才会给出合理的结果。

您的代码效率很低,因为您不需要对整个数组进行排序来获得最接近的颜色。相反,您应该循环遍历数组,并跟踪最短距离。

例如:

代码语言:javascript
复制
Array.closest = (function () {
    function dist(s, t) {
        if (!s.length || !t.length) return 0;
        return dist(s.slice(2), t.slice(2)) +
            Math.abs(parseInt(s.slice(0, 2), 16) - parseInt(t.slice(0, 2), 16));
    }

    return function (arr, str) {
        var min = 0xffffff;
        var best, current, i;
        for (i = 0; i < arr.length; i++) {
            current = dist(arr[i], str)
            if (current < min) {
                min = current
                best = arr[i];
            }
        }
        return best;
    };
}());

请注意,在此更改之后,Array.closest()将返回单个值而不是数组,因此您需要在代码中进一步删除[0]

票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17175664

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档