Javascript数组拼接而不更改索引

Javascript数组拼接而不更改索引,javascript,arrays,indexing,Javascript,Arrays,Indexing,我正在进行聊天,并使用数组来容纳用户。我的问题是: User1通过push连接并在数组中获得索引0。 User2通过push连接并在数组中获得索引1 User1断开连接并通过拼接移除 现在User2变成了索引0 User1重新连接,并通过push获得索引1 User2断开连接,索引1被删除,现在是User1 这当然会引起问题 所以我的问题是,如何在不改变其他元素索引的情况下从数组中删除该项?我在这里走错了吗?与其使用splice()从数组中删除项,为什么不直接将值设置为null或未定义的 然后,

我正在进行聊天,并使用数组来容纳用户。我的问题是:

User1通过push连接并在数组中获得索引0。 User2通过push连接并在数组中获得索引1

User1断开连接并通过拼接移除

现在User2变成了索引0

User1重新连接,并通过push获得索引1

User2断开连接,索引1被删除,现在是User1

这当然会引起问题


所以我的问题是,如何在不改变其他元素索引的情况下从数组中删除该项?我在这里走错了吗?

与其使用
splice()
从数组中删除项,为什么不直接将值设置为
null
未定义的

然后,在添加新用户时,只需扫描阵列即可找到第一个可用插槽

javascript数组只是项目列表——它们没有像您在PHP中可能熟悉的那样被设置为特定的键。因此,如果您想在数组中保持相同的位置,就不能删除其他项-您需要保留它们,并将它们标记为空


您可以扫描以下内容:

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

另一种选择是使用javascript对象而不是数组

大概是这样的:

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

但是,您丢失了array
length
属性,因此您必须自己跟踪最大用户数。

删除数组元素而不会遇到重新索引问题

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

现在arr2是========>>['a'、'c'、'd'、'e'、'f']

使用
删除
而不是
拼接

>a=['1','2','3']
<数组[“1”、“2”、“3”]
>删除[1]
a
<数组[“1”,未定义×1,“3”]
>a.长度
< 3

我相信,根据您的具体环境,有多种解决方案可以发挥作用。我有一个使用React的项目,在将数组中的对象设置为undefined时遇到了类似的问题,因为在代码的其他地方,我会得到一个错误,比如
找不到未定义的{key}
…同样的情况发生在
null
…我现在很好的解决方案是简单地重新创建整个数组,我可以这样做,因为这不是一个超长的列表。更改为符合您的描述:

let newUsers = [];
users.forEach((u, i) => {
  if (u.isOnline) newUsers[i] = u;
});
this.setState({ users: newUsers });
…就是这样。在我的例子中,我有一个选择食谱的列表。如果配方从整个配方列表中删除,则会将其从选择列表中删除,其中所选索引指示它是哪道“菜”(即开胃菜、主菜、甜点),因此索引很重要


另一个解决方案是使用用户ID作为数组的索引。当用户联机时,您可以设置
onlineUsers[user.ID]=user//或true或user.Name或任何内容

只需将字段设置为null“这当然会导致问题。”-为什么“当然”?这完全可以接受,这取决于其他代码如何使用数组。(也就是说,您的其他代码可以不依赖于数组索引的方式编写。)话虽如此,您可以使用对象而不是数组……感谢您的回复。我曾考虑过使用delete,因为它比让索引随着每个新用户的增长而增长,并且让索引增长得非常大要好。请您解释一下如何“扫描”并查找,然后将其分配给数组。更准确地说,如何扫描、分配(如果可用),如果没有,则推到最后?假设通过将插槽设置为
null
“清除”插槽,则可以使用
yourArray.indexOf(null)
获取第一个可用插槽的索引。如果它返回
-1
,这意味着没有空条目,那么您可以
.push()
@nnnnnn谢谢,我忽略了这一点。我更新了我的示例以使用
indexOf
。这是如何不改变索引的?c移到索引1,该索引应该保持在2,除非我误解了OP问题。
a.filter(x=>x)。length
将给出长度2I我假设这是预期的,正如问题所问的那样:>在其他元素的索引不改变的情况下,我如何从数组中删除该项Yep,我只是想加上它作为一种获取非空索引长度的方法。哦,对不起,我误读了。:)是的,确实可以获得已定义元素的长度。:)