5

I have an array that is very dynamic, there are new elements all the time, and other elements are removed.. The problem is that sometimes, under some circumstances, it's possible some of the elements to stay in the array forever and that is NOT what I want. Every element should be removed from the array within 15 seconds, if not, the array should remove that element automatically.

For example, in the code below, we have an array with three elements:

var array = ['e1', 'e2', 'e3'];

After 5 seconds I am adding 2 more elements in the array:

array[3] = 'e4';
array[4] = 'e5';

Now, let's say that the first 3 elements are inserted in the array in 12:00:00pm, and the second 2 elements in 12:00:05pm. I want the first 3 elements to be removed in 12:00:15pm, and the second 2 elements in 12:00:20pm......Etc....

Are there any ideas on how to solve this problem?

2
  • 1
    Can you post your code, please? It's hard to say how to fix when we don't know what you are doing. Commented Sep 23, 2016 at 21:38
  • I can't post the whole code because it's too big and complex, but I've added a simple example with explanation for my "problem". Commented Sep 23, 2016 at 21:44

3 Answers 3

5

Generally, when you are adding items to an array, you don't want to assume the position they will exist at. Instead of array[3] = 'e4', do array.push('e4'). This will make your life easier, and less bug-prone.

Because you need to associate times with each item, it might be wise to use objects for this in place of strings.

// create the array and push some objects into it
var array = []
array.push({createdAt: Date.now(), value: 'asdf'})
array.push({createdAt: Date.now(), value: 'asdf'})

Then, in an interval, you can check the createdAt values of each of the objects and decide if you want to kick them out of the array.

var maxLifespan = 5000
// check once per second
setInterval(function checkItems(){
    array.forEach(function(item){
        if(Date.now() - maxLifespan > item.createdAt){
            array.shift() // remove first item
        }
    })
}, 1000)

Using array.shift() assumes that you will always push new items onto the end of the array, so they will always be sorted chronologically.

If you need the array to be not chronologically sorted, then you'd need to use a method for removing elements at a specific index in an array (hint: NOT delete). Use array.splice to achieve this.

Sign up to request clarification or add additional context in comments.

4 Comments

This solution looks great, but can you tell me how to remove the items by value manually? Because sometimes, the user removes the elements before the timeout.
Use array.splice to remove elements from the array. I've expanded the answer.
Hmmm, I can't use array.splice because I don't know at what position is the value that I want to remove. For example if I have two values, "v1" and "v2", I don't know if v1 is at position 0, or 1. I only know that the item in the array that contains v1 is no longer needed.
See this other SO answer: stackoverflow.com/questions/8668174/…
3

You'll need to store a reference to when you inserted the values into the array in order to be able to remove them at a certain point. You might want to use a plain JavaScript object for this:

var map = {};

map[Date.now()] = ['a', 'b'];
console.log(map);

setTimeout(function() {
  map[Date.now()] = ['c', 'd'];
  console.log(map);
}, 5000);

setInterval(function() {
  var times = Object.keys(map);
  
  times.forEach(function(time) {
    if(Date.now() > (+time + 14000)) {
      delete map[time];
    }
  });
  
  console.log(map);
}, 1000);

Essentially I'm saving the times as the keys, and the array of items as the value. (Click "Run code snippet" above to see the console output to see how it behaves).

Basically we set up a "cron job" (simple setInterval) that runs every second and checks if the time the key was created is less than 14 seconds ago (not 15 seconds, since the cron job runs every second). Then it simply deletes that key from the object.

1 Comment

This would work as long as you never need to insert multiple items at the same time.
2

You can add elements to the array with a function like this:

function insert(array, element) {
    array.push(element);

    setTimeout(() => {
        const index = array.indexOf(element);
        if (index >= 0) {
            array.splice(index, 1);
        }
    }, 15000);
}

This way you would make sure that the element is removed after ~15 seconds no matter what. Obviously it will work 100% correctly with objects/arrays (referential types), but if you store primitives like strings or numbers then if you have more than 1 such primitive value in the array, you might end up removing the other copy of the value, but in the end every element gets removed after ~15 seconds.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.