skip to Main Content

I have an array with some numbers

[0, 0.1, 0.2, 0.3, 0.6, 0.8, 1]

how do I remove numbers that are close to each other less than or equal to 0.2 threshold and put the average of those values instead,
so the above array becomes

[0.2, 0.8]

0.2 because [0, 0.1, 0.2, 0.3] are close to each other so they become (0 + 0.1 + 0.2 + 0.3) / 4 = 0.2

0.8 because [0.6, 0.8, 1] are close to each other so they become (0.6, 0.8, 1) / 2 = 0.8

2

Answers


  1. In the case, that the only thing that matters is the difference to the next neighbour, it’s quite easy. See comments in the code …

    function simpleCluster(input, diff) {
      let 
        result = [],
        sum = input[0],
        count = 1;
    
      if (!input.length) 
        return [];
    
      for (let i = 1; i < input.length; i++) {
        //if the current value is too far away from the previous neighbour
        //calculate the average
        if ((input[i] - input[i - 1]) > diff) {
          //to round to 1 decimale multiply by 10,
          //then round to an integer and then divide by 10
          result.push(Math.round(10 * sum / count) / 10);
          //reset sum and count
          sum = 0;
          count = 0;
        }
        //add the current value to the sum and increase the count
        sum += input[i];
        count++;
      }
    
      if (count > 0)
         result.push(Math.round(10 * sum / count) / 10);
      
    
      return result;
    }
    
    console.log(simpleCluster([], 0.2));
    console.log(simpleCluster([0], 0.2));
    console.log(simpleCluster([0, 0.1, 0.3, 0.5, 0.9, 1, 1.3], 0.2));
    console.log(simpleCluster([0, 0.1, 0.2, 0.3, 0.4, 0.6, 0.6, 0.7,0.8], 0.2));
    Login or Signup to reply.
  2. You could do this by iterating over every element of the array and keeping a temporary close array. If close is empty, or the current element and the last element in close‘s difference is less than the threshold, then you can add it to close. If not, then average close and add it to the output array. Note that floating point math gets a bit weird here, you can use this rounding trick.

    const fixFloat = n => parseFloat(n.toPrecision(12))
    
    function average(arr) {
      let sum = 0;
      for (const el of arr) sum += el;
      return fixFloat(sum / arr.length);
    }
    
    function closeRemove(arr, threshold) {
      arr = [...arr].sort()
      const res = [];
      let close = [];
      for (let i = 0; i < arr.length; i++) {
        const diff = fixFloat(arr[i] - close[close.length-1]);
        if (close.length == 0 || diff <= threshold) {
          close.push(arr[i])
        } else {
          res.push(average(close));
          close = [arr[i]];
        }
      }
      res.push(average(close));
      return res;
    }
    
    const arr = [0, 0.1, 0.2, 0.3, 0.6, 0.8, 1];
    console.log(closeRemove(arr, 0.2));

    Note that in your question, the numbers 0, 0.1, 0.2, 0.3 all have a difference of less than 0.2, so they should be averaged together. Their average is 1.5, not 2.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search