简体   繁体   English

JavaScript Array.Splice()不会删除条目

[英]Javascript Array.Splice() doesn't remove entry

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. 如果某个条件为真,我试图从数组中删除一个条目,但是当我console.log对象数组时,该对象没有被删除,我很困惑为什么。 Am I using the Splice() function correctly? 我是否正确使用Splice()函数?

    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");
    }
});    

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); 

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. 可能更好或更清洁的方法是不使用forEach,而仅使用过滤器

Example: 例:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM