【问题标题】:How to remove contents from list如何从列表中删除内容
【发布时间】:2022-01-05 11:41:14
【问题描述】:

我对编码很陌生。有没有其他方法可以编写此代码以从 c# 中的列表中删除内容?

public void RemoveItem(string itemDescription)
{
    MenuItem found = new MenuItem(false, 0, "", ""); // must be a better way - to fix

    foreach (MenuItem item in MenuItems)
    {
        if (item.Description == itemDescription)
        {
            found = item;
        }
    }

    MenuItems.Remove(found);
}

【问题讨论】:

  • "必须是更好的方法" 是的,分配null 并检查它是否为空,您将其删除。
  • MenuItems 是什么类型?如果是List<MenuItem>,你可以做MenuItems.RemoveAll(item => item.Description == itemDescription);
  • MenuItems 上可能有一种方法可供您使用,但它在这里更精简,IMO,在if 中执行MenuItems.Remove(item); return; 并省去found 变量。
  • @JohnathanBarclay 这将删除所有满足条件的菜单项,但 OP 的代码仅删除满足条件的最后一个菜单项。
  • @SomeBody 是的,我假设只删除最后一个匹配的项目不是预期的行为。

标签: c# list


【解决方案1】:

有几种方法可以改进此代码。其中一些已经被提及。


正如@tim-schmelter 评论的那样

// removes the last matching occurrence from the menu and avoids the "dummy" object
public void RemoveItem(string itemDescription)
{
    MenuItem found = null; // this is better

    foreach (MenuItem item in MenuItems)
    {
        if (item.Description == itemDescription)
        {
            found = item;
        }
    }

    if (found != null)
        MenuItems.Remove(found);
}

最初由@SomeBody 回答

// removes the first matching occurrence from the menu
public void RemoveItem(string itemDescription)
{
    foreach (MenuItem item in MenuItems)
    {
        if (item.Description == itemDescription)
        {
            MenuItems.Remove(found);
            break; // or return;
        }
    }
}

// same but replacing the loop with a LINQ approach
public void RemoveItem(string itemDescription)
{
    MenuItem found = MenuItems.FirstOrDefault(item => item.Description == itemDescription);

    if (found != null)
        MenuItems.Remove(found);
}

// removing all occurences (assumes that MenuItems is from type `List<MenuItem>`
public void RemoveItem(string itemDescription)
{
    MenuItems.RemoveAll(item => item.Description == itemDescription);
}

// assuming List<MenuItem>, removing the first occurrence only
public void RemoveItem(string itemDescription)
{
    int index = MenuItems.Find(item => item.Description == itemDescription);

    if (index >= 0)
        MenuItems.RemoveAt(index);
}

【讨论】:

    【解决方案2】:

    我假设MenuItemsList&lt;MenuItem&gt;

    在这种情况下,正如 Johnathan 在 cmets 中所说,MenuItems.RemoveAll(item =&gt; item.Description == itemDescription); 将删除列表中符合您的条件的所有元素,这可能是最有效的选择:

    public void RemoveItem(string itemDescription)
    {
        MenuItems.RemoveAll(item => item.Description == itemDescription);
    }
    

    不过,理想情况下,我会使用 ID 字段来确保您确实删除了正确的元素。

    【讨论】:

      【解决方案3】:

      从性能的角度来看,如果列表变得非常大或经常被遍历(希望菜单列表不是这种情况),则另一种解决方案特别有意义。

      到目前为止,大多数给出的答案都需要两次查找(一次用于查找项目,一次用于删除项目),或者通过调用谓词函数需要一些开销。

      以下可能是最快的方法,并且适用于每个实现 IList&lt;T&gt; 的集合:

      // remove last matching item
      public void RemoveItem(string itemDescription)
      {
          for (int i = MenuItems.Count - 1; i >= 0; i--) // reverse for-loop, to avoid Count property call on each iteration
          {
              if (MenuItems[i].Description == itemDescription)
              {
                  MenuItems.RemoveAt(i);
                  return;
              }
          }
      

      【讨论】:

        【解决方案4】:

        @geraldmayr 的回答很棒。

        我唯一要改变的是 LINQ 中原始答案的方法,使其成为一个干净的内衬。

            public static void RemoveItem(string itemDescription)
            {
                menuItems.Remove(menuItems.First(menuItem => menuItem.ItemDescription == itemDescription));
            }
        

        【讨论】:

        • 你是对的。 List&lt;T&gt;.Remove() 接受空值。但是为了额外查找列表中绝对不存在的null 的成本。
        • 如果没有找到满足条件的元素,List&lt;T&gt;.Find() 将抛出 ArgumentNullException,因此不可能进行额外的查找。但这是我的意图,因为如果您尝试删除不存在的项目,我认为正确的行为是抛出异常。
        • 我的意思是,如果没有找到与项目描述匹配的项目,Find 将返回null,因此Remove 将与null 一起调用,从而导致在@ 中进行附加遍历987654329@
        • 哦,你是对的。感谢您的指正。我混淆了List&lt;T&gt;.Find()List&lt;T&gt;.First(),如果没有找到满足条件的元素,它会抛出异常。我现在要编辑答案。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-09-23
        • 1970-01-01
        • 2016-04-26
        • 1970-01-01
        • 2018-01-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多