JavaScript: Trimming Array Length by Removing Elements

I have been working on developing a JavaScript function that can remove elements from an array to meet a specific length, ensuring that the "gaps" are evenly distributed across the array. The ultimate goal is to simplify polygon vertices for drawing on a canvas.

Here is the approach I have taken:

https://i.sstatic.net/H6oSl.png

This is the code snippet I have come up with:

function simplify(array, vertices) {

  // Calculate gap size
  var gap = array.length - vertices;
  gap = Math.floor(array.length / gap);

  var count = 0;
  var result = [];

  // Populate a new array without gaps
  for (var i = 0; i < array.length; i++) {
    if (count == gap) {
      count = 0;
    } else {
      result.push(array[i]);
      count++;
    }
  }

  // Remove one item in the middle if the resulting length is odd
  if (result.length > vertices) {
    result.splice(Math.floor(result.length / 2), 1);
  }
  return result;
}

// The current implementation is giving unexpected results depending on input length!
// The expected output should be an array with a length of 3
console.log(simplify([
  { x: 10, y: 20 },
  { x: 30, y: 40 },
  { x: 40, y: 50 },
  { x: 50, y: 60 }
], 3))

Despite my efforts, it appears that this function works only intermittently, leading me to believe there may be issues within the mathematical calculations. Can someone provide insight into an improved algorithm or identify any mistakes I might be making?

Answer №1

I approached this problem using a method similar to how I handle nearest-neighbor texture lookups. The step variable, which is a floating point number greater than zero, is rounded down to the closest lower index. However, when 'floor(i*step)' ends up being greater than 'i', it takes its first leap forward.

   function simplify(array, vertices){

      vertices = vertices || 1;///Avoid division by zero

      var result = [];

      var step = array.length/vertices;

      for(var i=0;i<vertices;i++){
         result.push(array[Math.floor(step*i)]);
      }

      return result;

   }


//Testing it out
   var testarr = [];

   for(var ai=0;ai<51;ai++){
      testarr[ai] = {
         x:ai,
         y:10*ai
      }
   }

   console.log(testarr.slice(0));

   var ret = simplify(testarr, 29);

   console.log(ret.slice(0));

By the way,

   function simplify_bilinear(array, vertices){

      var result = [];

      var step = array.length/vertices;

      for(var i=0;i<vertices;i++){
         var fistep = Math.floor(i*step);//The nearest neighbor index
         var current = array[fistep];//This element
         var next = array[fistep+1];//The next element
         var mix = (i*step)-fistep;//The fractional ratio between them. As this approaches 1, the mix approaches the next value.
         //mix = mix * mix * (3 - 2 * mix);//Optional (s-curve) easing between the positions. Better than linear, anyway.
         //Alternately to the above//mix = Math.sin((mix*2 - 1)*Math.PI)*.5+.5;///for a sinusoid curve
         //True Bezier would be optimal here but beyond this scope 
         var mixed_point = {
            x:current.x+(next.x-current.x)*mix,//basic mixing, ala 'mix' in your average math library
            y:current.y+(next.y-current.y)*mix,
         }
         result.push(mixed_point);
      }

      return result;

   }

is a bilinear magnification filter that can be used if you want to increase the count instead of decreasing it. This algorithm could branch out if the desired length ('vertices') exceeds the 'array.length'. It's also handy for software audio synthesis purposes.

Answer №2

Perhaps this advice could be useful here

Imagine you possess a string with a length of n, yet you desire it to be the length of m. You have an array of n-2 elements to choose from and m-2 elements to pick for your new array. Now, let's assume that you've currently selected i elements and surpassed j elements. If i/j is less than (m-2)/(n-2), then you are falling behind. It may be advisable to select another element. To attain a evenly distributed selection, what you need to determine is whether (i+1)/(j+1) or i/(j+1) aligns better with your goal of (m-2)/(n-2). If exceeding the limit isn't a concern, you can utilize a bit of algebra to deduce that this equates to determining if (i+1)(n-2) - (j+1)(m-2) exceeds or falls below (n-2)/2; surpassing indicates i is preferable (thus, avoid selecting this one), while falling short implies i+1 is the better choice.

Answer №3

To reduce the length of an array by removing items, you can use the Array.splice() method.

For instance, if your desiredLength = 3, and you have an array = [1,2,3,4,5].

 array.splice(0, desiredLength).length == desiredLength
should return true.

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

Is it possible for me to pass a reference to a specific object's instance function?

Can JavaScript allow you to pass a function reference to a specific object's function, similar to what can be done in Java? Let's take a look at this code snippet: _.every(aS, function (value) { return exp.test(value); }); What if we want ...

Is there a way to transpile a dependency within the node_modules directory when using Nuxt 2?

I have come across challenges when transpiling node_modules with Nuxt, but the latest version of Nuxt (2.0) seems to have addressed this issue by introducing a transpile option in the nuxt.config.js file. https://nuxtjs.org/api/configuration-build/#transp ...

Utilize vue.router to navigate to a specific absolute URL

I've been searching for examples on how to manage routes within the application and they all seem to suggest using this syntax: this.$router.push({name: RouteName}) However, I'm curious about making a redirection using an absolute path. I attem ...

The functionality of clicking on a jQuery-generated element seems to be malfunctioning

When using Jquery, I am able to create an element and assign it the class .book: jQuery('<div/>', { name: "my name", class: 'book', text: 'Bookmark', }).appendTo('body'); I then wanted to add funct ...

Switching between playing and pausing on multiple audio tracks

I have a collection of audio files with custom play/pause buttons that I've implemented. Each audio file is assigned a dynamic class, such as custom-aud-0, custom-aud-1, custom-aud-2, and so on... Here is my toggle function: togglePlay(c, index) { ...

Attempting to utilize React Router V5 to display various layout designs

I have a React application with two different layouts: the "main layout" and the "auth layout". I have noticed that while the main layout pages function correctly, the auth layout pages do not seem to load. When attempting to access "/login", I am directed ...

Switching tabs automatically using JavaScript or jQuery

I successfully created a tabbing system with four tabs using jQuery. However, I am looking to enhance it by implementing an automatic looping feature that switches tabs every 5 seconds. While I can manually trigger each tab click event, I am unsure of how ...

An in-depth guide on implementing the Module Pattern in Typescript for an established JavaScript Module Pattern

I am relatively new to both Javascript and Typescript. I have been tasked with converting Javascript code to Typescript. I have come across a Module pattern that seems to return itself instead of exposing private methods and properties (please correct me ...

"Attempting to send JSON data via JsonResult is unsuccessful when trying to send a JSON object directly or using JSON

In my project, I have a class that looks like this: I've created a JsonResult method in the controller which takes an object of this class as a parameter: [HttpPost] public JsonResult NewAreaCode(AreaCode model) { return Json ...

Extracting HTML elements between tags in Node.js is a common task faced

Imagine a scenario where I have a website with the following structured HTML source code: <html> <head> .... <table id="xxx"> <tr> .. </table> I have managed to remove all the HTML tags using a library. Can you suggest w ...

How does thinking in ReactJS differ for someone with an AngularJS background?

Although I have experience with AngularJS, I am eager to dive into the world of ReactJS. I'm particularly intrigued by ReactNative and its potential to transform mobile apps. Can you explain how the mindset and architecture of a React application co ...

Why is the v-for directive malfunctioning and am I correctly displaying it in the template?

I'm new to working with Vuejs and recently created a mock dataset using JSON. The JSON file consists of an array containing 3 objects. Although console.log shows that Axios.get(URL) is fetching the data correctly, the v-for directive doesn't seem ...

The width of the <ul> element does not properly accommodate the width of the <li> elements during the animation that updates the width of the <li>

I am currently working on implementing a typing animation in React. The li element has an animation that recursively changes its width from 0px to 100%. However, I have noticed that when the width of the li changes, the parent ul does not adjust its width ...

Receive immediate updates of the text input in real-time using the onkeydown event handler in Javascript

I attempted to display the content of the input box in a message div simultaneously, however, the output always seems to be one step behind. function showWhatsWritten(){ var tempText; tempText = document.getElementById("text").value; document.getEle ...

Dropdown functionality in JavaScript and Bootstrap

Struggling with getting the bootstrap dropdown to change class on click? Don't worry, I've managed to make it change from "+" to "-", but now I'm facing an issue. When I click on the second dropdown, the one I clicked before doesn't cha ...

Discover the Value of an Object Property in JavaScript

Exploring different ways of accessing property values in JavaScript $(document).ready(function () { var itemList = [{ id: 1, name: 'shohel' }, { id: 2, name: 'rana' }, { id: 3, name: 'shipon' }]; //st ...

How can Jquery automatically populate a list-box with the values entered in a text-field?

I am trying to retrieve a value from a text field and add it to a list box using my jQuery code. JS:- { $('#btn_AddToList').click(function( { var select = document.getElementById('lst_Regions'); var region = $('#txt_Regio ...

Save an automatically generated number into a variable and use it to reference an image file for display. This process can be accomplished using JavaScript

I'm having trouble getting my images to display randomly on a page. The images are named 0 - 9.png and I am using a pre-made function for random number generation. However, when I try to call on this function later down the page, nothing appears. It ...

The script tag is utilized in the head section of a website for the production environment, but is not used in the

I have inserted an external script tag into the head section of a website - I only want to use it in the production environment and not in the testing (staging) environment. The application is developed with React, deployed using Google Cloud Platform for ...

Accessing a service instance within the $rootScope.$on function in Angular

I'm looking for a way to access the service instance variable inside the $rootScope in the following code. myapp.service('myservice',function($rootScope) { this.var = false; $rootScope.$on('channel',function(e,msg) { v ...