loading...

How to Decimate an Array.

adam_cyclones profile image Adam Crockett ・1 min read

An interesting use case arrived yesterday, I loved the simplicity of the code so I thought I'd share it.

Code: boom 💣

export function decimateArray(arr, passes = 1, fidelity = 2) {
  let tmpArr = arr.filter((_, index) => index % fidelity === 0);
  passes--;
  if (passes) {
    tmpArr = decimateArray(tmpArr, passes, fidelity);
  }
  return tmpArr;
}

Use case:

"I have a large array of xy coordinates, I need it to draw freehand on canvas but it's too much data to work with quickly, I just want to draw an approximate polygon. I want the array to be smaller so I can more efficiently loop through the data and I dont care about all of the data just the start and end."

How?

An array is fed in, if the index of the data is modulus of a passed in fidelity then keep this data, also recursively run this dataset through itself by a given number of passes.

In english please?

Large array goes in, smaller array with less detail comes out.

Posted on by:

adam_cyclones profile

Adam Crockett

@adam_cyclones

I work at ForgeRock as Staff UI Engineer, I play with all sorts really. Lately WASM is my toy of interest.

Discussion

pic
Editor guide
 

I would suggest 4 improvements (3 minor and 1 critical)

Critical bug

1) Provide the fidelity parameter as argument to the function, otherwise will only have a value other than 2 in the first step of the recursion;

Minor suggestions

1) Reduce LOC by decreasing by one in the if statement;
2) Remove obsolete else branch;
3) No need to reassign the variable, just return the result right away;

function decimateArray(arr, passes = 1, fidelity = 2) {
    const filteredArray = arr.filter((_, index) => index % fidelity === 0);

    if (--passes) {
        return decimateArray(filteredArray, passes, fidelity);
    }

    return filteredArray;
}

const parameters = [
    Array.from({ length: 100 }, (_, i) => i + 1),
    2,
    4,
];

const decimatedArray = decimateArray(...parameters);

console.log({ decimatedArray }); // { decimatedArray: [ 1, 17, 33, 49, 65, 81, 97 ] }

BTW sorry if I sound picky...

 

Array from with a function callback isn't as fast as mapping an empty array from an Array constructor. 🤣

It's not the point that it's buggy, it's important that you can take my crappy code and make something better, success. Still the failure to pass args recursively is something il fix.