简体   繁体   中英

Javascript Array Splice without changing the index

I am working on a chat and using an array to hold the users. Here is my problem:

User1 joins and is given Index 0 in the array via push. User2 joins and is given Index 1 in the array via push.

User1 disconnects and is removed via splice.

NOW User2 becomes Index 0.

User1 reconnects and is given Index 1 via push.

User2 disconnects, and Index 1 is removed which is now User1.

This is of course causing a problem.

So my question is how can I remove the item from the array without the index of the other elements changing? Am I on the wrong track here?

Instead of removing the items from the array with splice() , why not just set the value to null or undefined ?

Then when you're adding a new user, you can just scan through the array to find the first available slot.

javascript arrays are simply lists of items - they're not keyed to a specific key like you might be familiar with in PHP. So if you want to keep the same position in the array, you can't remove other items - you need to keep them, and just mark them as empty.


You might scan through something like this:

var users = [];
function addUser(user) {
    var id = users.indexOf(null);
    if (id > -1) {
        // found an empty slot - use that
        users[id] = user;
        return id;
    } else {
        // no empty slots found, add to the end and return the index
        users.push(user);
        return users.length - 1;
    }
}
function removeUser(id) {
    users[id] = null;
}

Use delete instead of splice .

> a = ['1', '2', '3']
< Array [ "1", "2", "3" ]

> delete a[1]
< true

> a
< Array [ "1", undefined × 1, "3" ]

> a.length
< 3

Another option is to use a javascript object instead of an array.

Something like this:

var users = {};

users[1] = 'user 1';
users[2] = 'user 2';

delete users[1];
alert(users[2]);        // alerts "user 2"
alert(typeof users[1]); // alerts "undefined"

You lose the array length property though, so you'll have to keep track of your max user number yourself.

I'm sure there is a variety of solutions that work depending on your specific context. I have a project using React and was having a similar issue when setting an object in an array to undefined because elsewhere in the code I would get an error like cannot find {key} of undefined ...the same happened with null ...my solution that now works fine is to simply recreate the whole array, which I can do in my case because it is not a super long list. Altered to fit your description:

let newUsers = [];
users.forEach((u, i) => {
  if (u.isOnline) newUsers[i] = u;
});
this.setState({ users: newUsers });

...something to that effect. In my case I have a list of selected recipes. If the recipe was deleted from the overall list of recipes, this removes it from the list of selections, where the selected index indicates which 'course' it is (ie Appetizer, Entree, Dessert) so the index matters.

Another solution could be to use your Users' ID as the index of the array. When a user comes online you can set onlineUsers[user.ID] = user //or true or user.Name or whatever

remove array elements without facing re-indexing problem

    var ind=[1,6]; //index positions of elements to remove
    var arr=['a','b','c','d','e','f','g']; // actual array
    var arr2 = arr.filter(function(item,index){
            if(ind.indexOf(index)== -1){
            return true;
    }});

now arr2 is ==========>> ['a','c','d','e','f']

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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