简体   繁体   English

从 IList 中查找和删除

[英]find and Remove from IList

I have a IList of users我有一个用户列表

private IList<User> _Players

I have a method to remove a specific user from the list我有一种方法可以从列表中删除特定用户

public virtual void RemovePlayer(User User)
{
    int index=_Players.Select(T=>T.ID).ToList().IndexOf(User.ID);
    _Players.RemoveAt(index);
}

I would like to know if there is a simpler way to remove a user from this list我想知道是否有更简单的方法可以从此列表中删除用户

How about this?这个怎么样? Use this if your parameter User is not part of _Players .如果您的参数User不是_Players一部分,请使用此_Players

 _Players.Remove(_Players.SingleOrDefault(x => x.ID == User.ID));

The SingleOrDefault() ensures that if the match is not found, that null is returned. SingleOrDefault()确保如果找不到匹配项,则返回 null。 When trying to remove null, no err occurs or is thrown.尝试删除 null 时,不会发生或抛出错误。

If the User objects you use are held within the _ Players list (same object references) you can just do如果您使用的User对象保存在 _ Players列表中(相同的对象引用),您可以这样做

_Players.Remove(user);

Otherwise if only the id matches you can do:否则,如果只有 id 匹配,您可以执行以下操作:

_Players.RemoveAll( p => p.ID == user.ID);

There are two scenarios, the user variable that you are passing to RemovePlayer有两种情况,您传递给RemovePlayeruser变量

  1. is actually contained in your list实际上包含在您的列表中
  2. has the same ID value, but is not the same object.具有相同的ID值,但不是同一个对象。

From your code sample it is impossible to say.从您的代码示例中无法说。

For the first case just call _Players.Remove(user) .对于第一种情况,只需调用_Players.Remove(user) For the second case implement the System.IEquatable<User> interface on User to define a default EqualityComparer<User> and then again call _Players.Remove(user) .对于第二种情况实现System.IEquatable<User>接口上User来定义默认EqualityComparer<User> ,然后再次调用_Players.Remove(user) This second scenario works in both cases.第二种情况适用于两种情况。

Depends, if you have implemented IEquatable on your user to compare by the ID , then you could simply do _Players.Remove(user) .视情况而定,如果您在用户上实现了IEquatable以通过ID进行比较,那么您可以简单地执行_Players.Remove(user)

Otherwise:除此以外:

var doomed = _Players.FirstOrDefault(p => p.ID == user.ID);
if (doomed != null)
   _Players.Remove(doomed);

Only in case if you have List<T> :仅在您有List<T>情况下:

All the mentioned algorithms with SingleOrDefault() / FirstOrDefault() require two traversals among list:所有提到的SingleOrDefault() / FirstOrDefault()算法都需要在列表中进行两次遍历:

1) first one to find an item by criteria 1)第一个按条件找到项目的人

2) second one to find index of item by its value found in step #1 2)第二个通过在步骤#1中找到的值来查找项目的索引

It's a bit more efficient to do like this instead:这样做会更有效率:

int index = list.FindIndex(i => criteria);

if (index >= 0)
  list.RemoveAt(index);

Just wanted to do the same, but couldn't find a standard way.只是想做同样的事情,但找不到标准的方法。
Decided to go code it myself for my int lists.决定为我的 int 列表自己编写代码。 This little one won't do double-pass on the list!这个小家伙不会做双关单上的!
You can replace int with object to work with classes.您可以将int替换为object以使用类。

public static bool FindAndRemoveFirst(this ICollection<int> list, Func<int, bool> predicate)
{
    var en = list.GetEnumerator();
    while (en.MoveNext())
    {
        if (predicate(en.Current))
        {
            list.Remove(en.Current);
            return true;
        }
    }
    return false;
}

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

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