2013-06-18 9 views
6

के आधार पर निकटतम रंग का नाम प्राप्त करें I दिए गए हेक्स-मान के आधार पर सबसे मिलान रंग का नाम प्राप्त करने का प्रयास करें। उदाहरण के लिए यदि हमारे पास हेक्स-रंग #f00 है तो हमें colorname red प्राप्त करना होगा।हेक्स-रंग

'#ff0000' => 'red' 
'#000000' => 'black' 
'#ffff00' => 'yellow' 

मैं वर्तमान में Levenshtein दूरी एल्गोरिथ्म का उपयोग निकटतम रंग नाम पाने के लिए, अब तक अच्छी तरह से काम, लेकिन कभी कभी नहीं की उम्मीद के रूप में।

उदाहरण के लिए:

'#0769ad' => 'chocolate' 
'#00aaee' => 'mediumspringgreen' 

तो किसी भी विचार कैसे परिणाम प्राप्त करीब के लिए?

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/

एक और बात प्रदर्शन है:

यहाँ है कि मैं क्या निकटतम रंग प्राप्त करने के लिए किया जाता है! ऐसा लगता है कि यह वास्तव में एक बड़ा मुद्दा है जो इसे वास्तव में धीमा बनाता है (क्या यह एल्गोरिदम है?)।

+1

अधिक समान रंगों के लिए [एचएसएल] (https://en.wikipedia.org/wiki/HSL_and_HSV) रंगों का उपयोग करना बेहतर होगा। – Sirko

+1

यदि आप सॉर्ट करने से पहले दूरी को पूर्ववत करना चाहते हैं तो आप सॉर्ट चरण ** ** बहुत ** तेज कर सकते हैं। – Pointy

+0

इसके अलावा मुझे यकीन नहीं है कि आप एक साधारण कार्टेशियन दूरी गणना का उपयोग क्यों नहीं करेंगे। (असल में मुझे लगता है कि मैं एक कोणीय समन्वय अंतरिक्ष में परिवर्तित हो जाऊंगा और एचएसएल या एचएसवी टर्न में दूरी करूंगा।) – Pointy

उत्तर

6

लेवेनशेटिन दूरी वास्तव में यहां उचित नहीं है, क्योंकि यह समानता के लिए चरित्र द्वारा चरित्र की तुलना करेगा। आपको प्रत्येक रंग को अलग से जांचना होगा, और आप 7900 से अधिक होने के लिए चाहते हैं।

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

ध्यान दें कि यह केवल उचित परिणाम देगा जब दोनों s और t 6-चरित्र रंग के होते हैं:

निम्नलिखित आप क्या चाहते हैं के लिए एक बहुत करीब आपके कोड के केवल न्यूनतम परिवर्तन के साथ हो रहा है हेक्स कोड।

आपका कोड अक्षम है क्योंकि आपको निकटतम रंग प्राप्त करने के लिए संपूर्ण सरणी को सॉर्ट करने की आवश्यकता नहीं है। आपको इसके बजाय सरणी के माध्यम से लूप करना चाहिए और सबसे छोटी दूरी का ट्रैक रखना चाहिए।

उदाहरण के लिए:

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] दूर करने के लिए की आवश्यकता होगी।

+0

वाह, बढ़िया! धन्यवाद अब तक: - * * उचित परिणाम जब दोनों एस और टी 6-वर्ण रंग हेक्स कोड हैं * कोई समस्या नहीं मैं 3 अंकों वाले हेक्स-रंगों को 6 में परिवर्तित करता हूं :) – yckart

+0

बीटीडब्ल्यू: पॉइंट [उल्लेख किया गया] (http: // stackoverflow .com/प्रश्न/17175664/प्राप्त-पर-निकट-रंग-नाम-निर्भर-ऑन-ए-हेक्स-रंग # comment24869664_17175664) जो सॉर्टिंग से पहले दूरी को सटीक बनाता है, इसे और भी तेज बनाता है ?! – yckart

+1

आपको बिल्कुल सॉर्ट नहीं करना चाहिए, मेरा संपादन देखें। –

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^