javascript - 如何比较仅采用 2 个参数的函数中的多个值?

标签 javascript algorithm

我正在尝试构建一个十六进制颜色比较器,该比较器比较数组中的值并删除相似的值,以保持像素最多的颜色。

这是输入的示例,数组的长度可以从 1 变为更多:

[…]
0: Array [ "ffffff", 12992 ]
1: Array [ "da542f", 3117 ] #similar
2: Array [ "da5630", 60 ]   #similar
length: 3

(index: Array [hexColor, NumberOfPixel])

输出看起来像这样:

[…]
0: Array [ "ffffff", 12992 ]
1: Array [ "da542f", 3117 ]
length: 2

我想到的是,由于下面的示例是 super 硬编码并会产生错误,我想避免在彼此内部有多个 if/else,hexColorCalc() 函数来自此 post :

FIDDLE >

// ordered by highest pixel
colors_lst = [
  ["333333", 6421], 
  ["da542f", 3117],
  ["da5630", 60]
]

console.log(colors_lst);

function hexColorDelta(array) {
  function hexColorCalc(hex1, hex2) {
    // get red/green/blue int values of hex1
    var r1 = parseInt(hex1.substring(0, 2), 16);
    var g1 = parseInt(hex1.substring(2, 4), 16);
    var b1 = parseInt(hex1.substring(4, 6), 16);
    // get red/green/blue int values of hex2
    var r2 = parseInt(hex2.substring(0, 2), 16);
    var g2 = parseInt(hex2.substring(2, 4), 16);
    var b2 = parseInt(hex2.substring(4, 6), 16);
    // calculate differences between reds, greens and blues
    var r = 255 - Math.abs(r1 - r2);
    var g = 255 - Math.abs(g1 - g2);
    var b = 255 - Math.abs(b1 - b2);
    // limit differences between 0 and 1
    r /= 255;
    g /= 255;
    b /= 255;
    // 0 means opposit colors, 1 means same colors
    return (r + g + b) / 3;
  }

  // Do nothing since nothing to compare
  if (array.length == 1) {
    console.log('length of array : 1');
    return array
  }

  // Just compare both values and erase the one with least pixel
  if (array.length == 2) {
    console.log('length of array : 2');
    var hex1 = array[0][0];
    var hex2 = array[1][0];


    if (hexColorCalc(hex1, hex2) > 0.9) {
      colors_lst = array.pop(); // Get ride of last item in array
      return colors_lst;
    }
  }

  // Problems 
  if (array.length == 3) {
    var hex1 = array[0][0];
    var hex2 = array[1][0];
    var hex3 = array[2][0];

    // if True, other if/else below won't be working
    if (hexColorCalc(hex1, hex2) > 0.9) {
      array.splice(2, 1);
    }

    if (hexColorCalc(hex1, hex3) > 0.9) {
      array.splice(3, 1);
    }

    if (hexColorCalc(hex2, hex3) > 0.9) {
      array.splice(2, 1);
    }

    return array
  }
}

console.log(hexColorDelta(colors_lst));

我注释掉了代码的工作原理,我在理解这个问题的正确算法时遇到了一些困难。如何避免硬编码并返回没有相似之处的正确列表?

最佳答案

为避免过度使用 if,尤其是对于组合会爆炸的较大数组,您可以依赖循环。以下是我在对您的代码进行一些清理后提出的解决方案:

// splits the hex value to its components
function splitHex(hex) {
    return {
        r: parseInt(hex.substring(0, 2), 16),
        g: parseInt(hex.substring(2, 4), 16),
        b: parseInt(hex.substring(4, 6), 16)
    };
}

// return number between 0 (opposit colors) and 1 (same colors)
function hexColorCalc(hex1, hex2) {
    // get red/green/blue int values of hex1
    const hex1Split = splitHex(hex1);
    // get red/green/blue int values of hex2
    const hex2Split = splitHex(hex2);
    // calculate normalized differences between reds, greens and blues
    const r = 1 - Math.abs(hex1Split.r - hex2Split.r) / 255;
    const g = 1 - Math.abs(hex1Split.g - hex2Split.g) / 255;
    const b = 1 - Math.abs(hex1Split.b - hex2Split.b) / 255;

    return (r + g + b) / 3;
}

// clears array from similar colors with threshold
function hexColorDelta(array, threshold) {
    // loop through array twice as a table to get all combinations
    for (let i = 0; i < array.length; i++) {
        for (let j = 0; j < array.length; j++) {
            // only remove the color in the second loop if similar
            if (i !== j && hexColorCalc(array[i][0], array[j][0]) > threshold) {
                array.splice(j, 1);
                j--;
            }   
        }
    }
    return array;
}

// test
const similar_1_2 = [["da542f", 3117], ["da5630", 60], ["333333", 6421]];
const similar_1_3 = [["da542f", 3117], ["333333", 6421], ["da5630", 60]];
const similar_2_3 = [["333333", 6421], ["da542f", 3117], ["da5630", 60]];
const similar_all = [["da5630", 60], ["da542f", 3117], ["da5630", 60]];
console.log(JSON.stringify(hexColorDelta(similar_1_2, 0.9)));
console.log(JSON.stringify(hexColorDelta(similar_1_3, 0.9)));
console.log(JSON.stringify(hexColorDelta(similar_2_3, 0.9)));
console.log(JSON.stringify(hexColorDelta(similar_all, 0.9)));

希望对您有所帮助。

关于javascript - 如何比较仅采用 2 个参数的函数中的多个值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47199429/

相关文章:

javascript - jQuery AJAX 附加到 Json 返回数据 "d:null"

javascript - Jquery 计数不正确?

algorithm - 给定一组二维坐标系中的点,如果我们只访问所有点一次,如何计算最小距离和路径?

java - 如何判断一个图是否有环?

algorithm - 在小于 O(n) 的时间内找到交换的元素?

javascript - 无法读取 null 的属性 'length' - 使用 css 显示 block (选择/onchange)

javascript - 简单的js框架,DOM。 (模块样式,如 jQuery)添加方法的问题

javascript - Vue2 : view-router exception when trying to use <router-view>

algorithm - 俄罗斯方 block 旋转算法

PHP 在连字符数组中查找缺失的数字