【问题标题】:How to remove int[] from List<int[]>?如何从 List<int[]> 中删除 int[]?
【发布时间】:2015-06-23 08:21:17
【问题描述】:

我对在 C# 中使用 List 作为数组还是很陌生。所以我在使用时遇到了问题。

我正在尝试使用RemoveList&lt;int[]&gt; 中删除int[]整数数组),但未能从List&lt;int[]&gt; 中删除int[]

代码如下:

List<int[]> trash = new List<int[]>()
{
     new int[] {0,1},
     new int[] {1,0},
     new int[] {1,1}
};
int[] t1 =  {0,1};
trash.Remove(t1);

这只是一个错误吗? 还是无法识别int[]

【问题讨论】:

  • 它们是不同的对象。您必须按索引或使用相同的参考删除
  • 不是错误。您正在尝试删除不在列表中的数组。您的第二次尝试Console.WriteLine(t1 == trash[0])。它们不一样。
  • 哦,非常感谢你们所有人。 :D

标签: c# arrays list


【解决方案1】:

问题在于每个数组类型都是引用类型,List 基于相等性删除项目,其中引用类型的相等性默认为引用相等性。这意味着,您必须删除与列表中完全相同的数组。

下面的例子效果很好:

int[] t1 =  {0,1};
List<int[]> trash = new List<int[]>()
{
            t1,
            new int[] {1,0},
            new int[] {1,1}
};
trash.Remove(t1);

【讨论】:

  • 您的意思是删除 same 数组?您必须使用对要删除的数组的引用,而不是重新创建具有相同内容的新数组,如代码示例中所示。或者,您可以使用基于索引的 RemoveAt
  • 如果有 2 个 int[] 具有相同的值但第一个来自 List 之外的值会发生什么,就像您在上述答案中所做的那样?
  • @GenesisMallari 值不重要,只有引用才重要。你真的要使用int[]吗?自定义类型(可能是结构)不是更合适吗?然后,您可以按照您想要的方式实现价值平等。或者,使用不同的集合 - 如果有明显的索引,请使用字典。如果您只关心顺序,请使用堆栈。
  • 这个问题只是我另一个更难的问题的一部分。我认为他们是我想念的东西,是的,你指出了这一点。我会等 80 分钟再问另一个问题。谢谢你的回答,真的很有帮助。
【解决方案2】:

如果您想删除与目标列表具有相同内容(以相同顺序)的所有列表,您可以使用List.RemoveAll() 和 Linq 的SequenceEqual()

List<int[]> trash = new List<int[]>
{
    new [] {0, 1},
    new [] {1, 0},
    new [] {1, 1}
};

int[] t1 = {0, 1};

trash.RemoveAll(element => element.SequenceEqual(t1));

Console.WriteLine(trash.Count); // Prints 2

虽然这很慢。如果可以的话,最好使用索引。

【讨论】:

    【解决方案3】:

    错误是数组列表使用引用类型数据。因此请使用 List 的 removeAt 方法,如下所示:

    List<int[]> trash = new List<int[]>()
    {
        new int[] {0,1},
        new int[] {1,0},
        new int[] {1,1}
    };
    trash.RemoveAt(0);
    

    使用 RemoveAt 您需要传递要从列表中删除的整数数组的索引。

    【讨论】:

      【解决方案4】:

      您的 t1 变量是数组的一个新实例。所以它不会等于列表中的第一个元素。

      试试:

      trash.Remove(trash[0]);
      

      trash.RemoveAt(0);
      

      【讨论】:

      • 在这种情况下,后一种选择要好得多,因为列表不必搜索数组。
      【解决方案5】:

      .Remove 方法查看元素的地址。如果它们相等,则将其删除。你应该这样做。

      int[] t1 =  {0,1};
      int[] t2 =new int[] {1,0};
      int[] t3 =new int[] {1,1};
      List<int[]> trash = new List<int[]>()
      {
           t1,t2,t3      
      };
      
      trash.Remove(t1);
      

      【讨论】:

        【解决方案6】:
        foreach(var x in trash)
        {
            if(x[0] == t1[0] && x[1] == t[1])
            {
                trash.Remove(x);
                break;
             }
        }
        

        这应该也可以

        【讨论】:

        • 它确实有效,但是是 O(n²)。您可以通过对 O(n) 进行基于索引的搜索来改进这一点。
        • 我认为实际上是 O(n*m) 其中 n 是列表大小,m 是数组大小
        • 我认为数组大小是恒定的,但是如果你想把这个放进去,那么它当然是 O(n*m) 对 O(n²*m)
        • 我不明白为什么应该是n^2...你能举个例子吗?
        • 问题是 Remove 是 O(n),更准确地说是 \Theta(n),你称它为 O(n) 次,总计 O(n^2)。 RemoveAt 也不是 O(1) 而是 O(n),但它只处理 i 之后的索引,其中 i 是它的参数。因此,您可以证明这只加起来为 O(n)。
        【解决方案7】:

        这只是因为您试图删除新项目。

        它的地址引用与列表中已经存在的对象不同。这就是它没有被删除的原因。

        Int 是值类型.. Int[] 是引用类型..

        所以当你用 Int list 来做的时候

        List<int> trash = new List<int>(){ 1, 13, 5 };
        int t1 = 13;
        trash.Remove(t1);//it will removed
        

        但对于 Int[]

        List<int[]> trash = new List<int[]>()
        {
            new int[] {0,1},
            new int[] {1,0},
            new int[] {1,1}
        };
        var t1 = {0,1};
        trash.Remove(t1);//t1 will not removed because "t1" address reference is different than the "new int[] {0,1}" item that is in list.
        

        删除-

        trash.Remove(trash.Find(a => a.SequenceEqual(t1)));
        

        SequenceEqual() 确定两个序列是否相等,方法是使用其类型的默认相等比较器比较元素。

        【讨论】:

        • 好吧,在值之前添加一个新的 int[] 后,它给了我同样的失败结果。
        • 现在你可以看到我的回答和描述......以及你的解决方案。 :)
        【解决方案8】:

        如果您想删除确切的序列,但无法删除确切的对象(来自其他地方的序列),您可以使用 lambda 表达式或匿名方法搜索正确的序列:

        List<int[]> trash = new List<int[]>
             {
                 new [] {0, 1},
                 new [] {1, 0},
                 new [] {1, 1}
             };
        
        int[] t1 = { 0, 1 };
        
        //using anonymous method
        trash.RemoveAll(delegate(int[] element) { return element.SequenceEqual(t1); });
        
        //using lambda expression
        trash.RemoveAll(element => element.SequenceEqual(t1));
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-06-07
          • 2016-07-02
          • 2012-09-28
          • 2014-06-28
          • 2015-09-22
          • 2017-06-25
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多