1

I'm trying to remove an entry from an array if a certain condition is true, but when I console.log the array of objects, the object has not been removed and I'm confused why. Am I using the Splice() function correctly?

    var itemsProcessed;
people.forEach(async function(peep, index, object){

    var d = new Date();
    var currenttime = d.getTime();
    if (peep.endtime < currenttime){
        var rolesub = guild.roles.find(r => r.name == roleNameSub);

        var user2 = await client.fetchUser(peep.id);
        var member = await guild.fetchMember(user2);

        member.removeRole(rolesub);

        object.splice(index, 1);  //This seems to go wrong...

        console.log(peep.id + " Lost subscription!");
        user2.send("Your subscription ended!");

    }
    itemsProcessed++;
    if (itemsProcessed === object.length){
        SaveJson(people, "users.json");
    }
});    
6
  • are you facing any error ?? if yes, post error please Commented Mar 7, 2019 at 11:56
  • and object is a parameter that receives the function,you can not modify it except if you call the function Commented Mar 7, 2019 at 11:56
  • 1
    Object.splice doesn't exist. It's a method of Array (not Object). What does the console say? Any errors? Commented Mar 7, 2019 at 11:57
  • @JeremyThille here variable object is array. he is fetching length of it at the end. Commented Mar 7, 2019 at 12:00
  • 1
    Ah, neat idea to call an Array "object" :) Commented Mar 7, 2019 at 12:00

2 Answers 2

1

Your problem is the fact you're splicing the same array you're iterating hence why the indexes will not be correct.

You should create a copy of the array before iterating it and remove elements from the original array by retrieving the index of the element you want to remove, take a look below.

arr.slice(0).forEach(function(item) {
    arr.splice(arr.indexOf(item), 1);
});

var arr = [{0:0},{i:1},{i:"test"},{i:"Something else"},{i:"Test"},5];
    
arr.slice(0).forEach(function(item) {

    if(item != 5)
        arr.splice(arr.indexOf(item), 1);
});
    
console.log(arr);

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

Comments

0

One thing you can consider and change is that when you are iterating the array, don't delete from it while iterating. Just mark the entry for deletion. Then, when you are done, filter out the ones that need to be removed.

For example:

people.forEach( (person,i) => {

   if( /* person needs to be removed from people */ ) {
       people[i] = null;  // use use array from 3rd parameter if you want to pass it in
   }
});

// then remove unwanted people

people = people.filter( person => person != null );

Or, if you don't want to set the person to null, then you can set a flag in the object instead to mark it for deletion.

Example:

people.forEach( (person,i) => {
   if( /* person needs to be removed from people */ ) {
       person.toBeDeleted = true;
   }
});

people = people.filter( person => person.toBeDeleted !== true );

What is probably an even better or cleaner approach is to not use forEach but just use filter only.

Example:

    people = people.filter( p_person => {
         if( /* person stays */ ) {
             return true;
         } else {
             return false;
         }
    });

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.