0

I am looking for a way to merge similar hsl colors together by a specific amount. Let's say I have the following three colors: 150, 50, 100, 149, 49, 100, 151, 51, 99. The result I am looking for should be a single value: 150, 50, 100.

Let me try to explain it better:

Example Data:

const colors = {
  red: [
    {h:151 , s:57 , l:100},
    {h:150 , s:5 , l:100},
    {h:155 , s:50 , l:100},
    {h:125 , s:100 , l:100},
    {h:132 , s:0 , l:100},
  ],
  green: [...],
  blue: [...]
}

Now let's say each array contains a lot of items, and I want to reduce the number of items by merging similar items together. The threshold must be a variable. The merging process is simply taking the average of all similar items.

I hope that my explanation is clear, it is quite hard to explain.

Vera Perrone
  • 369
  • 1
  • 15
  • 1
    Can we have a look of what you have tried so far? – Ayaz Ali Shah Sep 14 '18 at 12:38
  • @AyazShah The thing is, I am not even sure how to think about this problem. If I am simply looping through the array, I need to check it's value, compare to each other item of the array. So I guess a two-dimensional loop is required. Is this the right way of thinking? – Vera Perrone Sep 14 '18 at 12:43
  • 2
    it is called [clustering](https://en.wikipedia.org/wiki/Cluster_analysis) – apple apple Sep 14 '18 at 12:43

1 Answers1

1

Here is something you can use as a start. What it does :

Ignore a value, if there are already a value that is matching (using threshold system);

What you want to do is very specific, so start with understanding this, then adapt it to your need. In case of coding trouble, we will help you.

Actually in here, we shouldn't create your code, but help you with yours. I feel in a good mood

const colors = {
  red: [{
      h: 151,
      s: 57,
      l: 100
    },
    {
      h: 150,
      s: 5,
      l: 100,
    },
    {
      h: 155,
      s: 50,
      l: 100,
    },
    {
      h: 125,
      s: 100,
      l: 100,
    },
    {
      h: 132,
      s: 0,
      l: 100,
    },
  ],
};

const tresholdH = 10;
const tresholdS = 100;
const tresholdL = 100;

function reduceArrayByTreshold(array) {
  return array.reduce((tmp, x) => {
    if (tmp.some(({
          h,
          s,
          l,
        }) => (x.h >= h - tresholdH && x.h <= h + tresholdH) &&
        (x.s >= s - tresholdS && x.s <= s + tresholdS) &&
        (x.l >= l - tresholdL && x.l <= l + tresholdL))) {
      return tmp;
    }

    return [
      ...tmp,
      x,
    ];
  }, []);
}

const colorsReduced = Object.keys(colors).reduce((tmp, x) => {
  tmp[x] = reduceArrayByTreshold(colors[x]);

  return tmp;
}, {});

console.log(colorsReduced);
Orelsanpls
  • 22,456
  • 6
  • 42
  • 69