使用 indexOf 从列表中删除对象?

Using indexOf to remove an Object from a list?

所以,我看到了这段代码:

removeOrder = (order) ->
    index = listOfOrders.indexOf(order)
    if index isnt -1
        listOfOrders.splice index, 1

其中 order 是这样的对象:

order = {
    id: whatever
    field1: whatever
    ...
}

现在可以正常工作了,因为作为参数传递的 order 正在引用 listOfOrders 中的某个对象,例如 removeOrder(listOfOrders[i])。但我的问题是,这安全吗?我的意思是,我认为最好遍历订单列表并搜索具有相同 ID 的对象,例如,然后将其删除。

据我所知,当我们搜索的对象是 "simple" 对象(数字、字符串等)时,indexOf 是可以的。

根据These docs for indexOf,indexOf使用严格相等===

var a = {id:1};
var b = {id:1};

a === a; // this is true
a === b; // this is false

所以对于对象来说一般来说是安全的

你确实需要在拼接之前检查 indexOf != -1

假设数组中只有一个对对象的引用,该函数按预期运行。

如果对象不在数组中(或者您使用数组中对象的克隆调用它),索引将为 -1,并且 splice 调用将删除最后一项在数组中。由于这不是一种合理的行为,因此确实应该对此进行检查(我看到你添加了)。

indexOf 方法对对象引用可靠地工作,但它自然必须寻找相同的对象。

寻找具有特定 属性 值的对象也可以,但它遵循相同的假设;该值必须在数组中恰好出现一次才能按预期工作。

var removeOrder = function(order)
{
  var index = listOfOrders.indexOf(order);
  if (index != -1)
    return listOfOrders.splice(index, 1); //for chaining?
  return listOfOrders;
}

如果预期目的是通过引用从数组中删除对象,则使用 indexOf 是安全的。

如果您想通过 id 删除第一个对象,比方说,您可以使用类似的东西:

var removeOrderById = function(orderId)
{
  var orders = listOfOrders.filter(function(item) 
  {
    return item.id == orderId;
  });
  if (orders.length > 0)
  {
    var index = listOfOrders.indexOf(orders[0]);
    return listOfOrders.splice(index, 1); //for chaining?
  }
  return listOfOrders;
}

结论:一切都与用例有关。