Find the most accurate color name corresponding to a hexadecimal color code

When given a hex-value, I aim to find the closest matching color name. For instance, if the hex-color is #f00, the corresponding color name is red.

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

Currently, I employ the levenshtein-distance algorithm to determine the closest color name, which generally works well but not always as expected.

For instance:

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

Are there any suggestions to improve the accuracy of the result?

Below is the function I created to find the closest color:

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/

Another concern is the performance. It appears there may be a significant issue causing slow processing (potentially related to the algorithm).

Answer №1

Using Levenshtein distance may not be the best approach in this case as it compares character by character for equality. It would be more effective to evaluate each color individually, where the proximity of 79 to 80 should be greater than to 00.

The following adjustment closely aligns with your requirements, making only minimal modifications to your existing code:

Array.closest = (function () {
    function distance(s, t) {
        if (!s.length || !t.length) return 0;
        return distance(s.slice(2), t.slice(2)) +
            Math.abs(parseInt(s.slice(0, 2), 16) - parseInt(t.slice(0, 2), 16));
    }

    return function (array, target) {
        return array.sort(function (a, b) {
            return distance(a, target) - distance(b, target);
        });
    };
}());

Keep in mind that this method works best when both s and t are 6-character color hex codes.

Your current implementation is inefficient because sorting the entire array is unnecessary to find the closest color. It would be more efficient to iterate through the array and track the shortest distance.

For instance:

Array.closest = (function () {
    function distance(s, t) {
        if (!s.length || !t.length) return 0;
        return distance(s.slice(2), t.slice(2)) +
            Math.abs(parseInt(s.slice(0, 2), 16) - parseInt(t.slice(0, 2), 16));
    }

    return function (array, target) {
        var minDistance = 0xffffff;
        var closestColor, currentDistance, i;
        for (i = 0; i < array.length; i++) {
            currentDistance = distance(array[i], target)
            if (currentDistance < minDistance) {
                minDistance = currentDistance
                closestColor = array[i];
            }
        }
        return closestColor;
    };
}());

After this update, Array.closest() will return a single value instead of an array, hence the need to remove [0] later in your code.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Use jQuery's change method to initiate a hidden file input

Want to create a fake file input using an anchor tag and trigger the hidden file input with jQuery? Looking for some advice on how to make this happen. Check out my current attempt here. I'm not sure if I'm on the right track with this, so any g ...

Removing a property from a JSON object when initiating an Ajax request in JavaScript

Looking for guidance on JavaScript and ajax as a beginner. I have a JSON with an output cell that I want to remove: { "cells": [{ "metadata": { "trusted": true, "collapsed": false }, ...

What is the correct way to iterate through a list of images fetched with getStaticProps and display them within the same component?

What is the proper way to map a list of images returned using getStaticProps? I had successfully implemented this by passing a prop to the gallery component in another page. However, I now want to consolidate all the getStaticProps code within the gallery ...

Making sure to consistently utilize the service API each time the form control is reset within Angular 4

In the component below, an external API service is called within the ngOnInit function to retrieve an array of gifs stored in this.items. The issue arises when the applyGif function is triggered by a user clicking on an image. This function resets the For ...

Encountering a 404 error while attempting to establish a connection between Express and React

My attempt to make a simple API request for bitcoin values is encountering some issues. When I enter in my Chrome browser, I receive a "Cannot Get /" message with a 404 error in the dev tools stating "GET 404 (Not Found)". However, when I visit , I succ ...

Controlling the visibility of components or elements in Angular through input modifications

Is there a more efficient way to handle button disabling and enabling based on email validation in Angular? I already have form controls set up, but want to make the process cleaner. The goal is to disable the "Get Started" button by default if the email a ...

Issue with visibility of pagination in AngularJS ui

I am facing an issue with pagination in my AngularJS UI application. I have a dataset that requires server-driven pagination due to its size. The problem I'm encountering is that the pagination element is not displaying on the page, even though I hav ...

Looking to extract the first URL from a string using JavaScript (Node.js)?

Can someone help me figure out how to extract the first URL from a string in Node.js? " <p> You left when I believed you would stay. You left my side when i needed you the most</p>**<img src="https://cloud-image.domain-name.com/st ...

Tips on pairing elements from a ngFor processed list with another list using ngIf

If we have a list such as the one shown below: elements = [ { id: 1, name: "one" }, { id: 3, name: "three" }, { id: 5, name: "five" }, { id: 6, name: "six" }, ]; lists = [ { id: 5, name: "five" }, { id: 9, ...

JavaScript - Utilizing jQuery to dynamically add and remove input fields

I have a form where input fields (groups) are added dynamically. Here's a glimpse of the complex form: FIDDLE The error on the console reads: Error: uncaught exception: query function not defined for Select2 s2id_autogen1 With existing fields in t ...

Tips for selecting a pagination page number in Python with Selenium

I've been struggling to figure out how to interact with the page numbers of a pagination class for a while now. Despite trying various methods, I can only manage to highlight the container of the number without being able to actually click on it. Bel ...

What is the best way to create a variable in a React component that requires asynchronously loaded data in order to be functional?

While I have a good understanding of passing data from one component to another using this.props, I am encountering difficulty in asynchronously fetching and storing values, such as from a database, that need to be accessed throughout the component. The ch ...

Transmit information using $broadcast when a button is clicked, and retrieve that information using $scope.$on

I am trying to create a function that will broadcast data from the server upon button click, and then navigate to a new route using $state.go('new-route'). In the controller of this new state, I want to retrieve the transmitted data. However, whe ...

No data is being retrieved by SWR

I'm struggling to make SWR work in my code. Despite trying multiple examples, I can't seem to get it functioning properly. It's frustrating because the code looks fine and should work. I feel like I must be missing something simple. Current ...

JavaScript alert box

I'm fairly new to the world of web development, with knowledge in CSS & HTML and currently learning TypeScript. I'm attempting to create a message icon that opens and closes a notifications bar. Here's where I'm at so far: document.getE ...

Encountering an error message stating "Please enable JavaScript to run this application" when making React API calls after deploying a ReactJs app on the Firebase server

I'm currently working on a React JS app that calls various APIs. The backend of this application is a NodeJs server deployed in GCloud. While everything runs smoothly when I test the React app locally, I encountered an issue after deploying it to Fir ...

"Failed authentication for client" in the testing environment of PayPal sandbox

I obtained the code from github and updated the Client ID & App Secret accordingly. It worked flawlessly. https://github.com/paypal-examples/docs-examples/tree/main/advanced-integration However, upon integrating the codes into my project, I encountered th ...

React Native formInput Component with Underline Decoration

Utilizing the FormInput element in React Native Elements, I have observed a line underneath each FormInput component. Interestingly, one line appears fainter than the other. https://i.sstatic.net/ZD8CI.png This is how the form looks: <View style={sty ...

What is the best way to determine total revenue by consolidating data from various tables within an IndexedDB database?

Seeking guidance on building a stock/sales application in JavaScript with Dexie.js. I need assistance in efficiently calculating the Total Sales amount without resorting to overly complicated recursive code that triggers multiple queries for a single produ ...

The Facebook SDK fails to activate in Internet Explorer

I am currently working on implementing a Facebook login using the JavaScript SDK. Everything is functioning correctly in most browsers, but I am experiencing issues with certain versions of Internet Explorer. The login functionality is not working on my l ...