【问题标题】:Remove duplicates from arraylist of objects从对象的arraylist中删除重复项
【发布时间】:2017-09-20 06:53:26
【问题描述】:

我正在尝试删除用“DataPerLabel”对象填充的 one 数组列表的重复项。

DataPerLabel 包含以下方法:getLabelname()、getLabelAdress() 和 getDataType()。

一些背景资料:

labelname、labelAdress 和 dataType 的值可以通过提交按钮设置为名为 allData 的数组列表中的 1 个对象。当第二次按下提交时,我想删除 arraylist 的那个对象。

图片:

我尝试过的一些代码:

if (submitButtonClicked == true) {
  if (MessageBox.Show("This is item is already set. Do you want to delete?", "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) {
    foreach(DataPerLabel item in allData) {
        if (item.getDataType().Equals(dataType) && item.getLabelAdress().Equals(adress) && item.getLabelName().Equals(label)) {
          allData.Remove(item);
        } else {

        }
    }
  } else {
    //no
  }

}

使用此代码,我收到以下错误:mscorlib.dll 中发生“System.InvalidOperationException”类型的未处理异常。

附加错误信息:集合已更改。

【问题讨论】:

标签: c# arraylist duplicates


【解决方案1】:

您正在尝试在 allData 列表中进行迭代,并且您也在尝试修改同一个列表。您可以继续删除其他列表中的数据(例如:removeItems),然后您可以删除项目。我的意思是:

   if (submitButtonClicked == true) {
      if (MessageBox.Show("This is item is already set. Do you want to delete?", "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) {
List<DataPerLabel> removeItems = new List<DataPerLabel>();
        foreach(DataPerLabel item in allData) {
            if (item.getDataType().Equals(dataType) && item.getLabelAdress().Equals(adress) && item.getLabelName().Equals(label)) {
              removeItems.Add(item);
            } else {

            }
        }
      } else {
        //no
      }

    foreach(DataPerLabel removeItem in removeItems ){
        allData.Remove(removeItem);
      }

}

【讨论】:

  • 没有第二个 foreach 会更简单,但有:allData.RemoveRange(removeItems);
  • 我用过这个方法,对我有用。谢谢大家!
【解决方案2】:

正如 OnurBulbul 所说,由于尝试修改正在迭代的列表,您会遇到异常。可能有很多不同的解决方案。我的建议是使用 LINQ:

var sortedList = from item in allData
                 where !(item.getDataType().Equals(dataType) && item.getLabelAdress().Equals(adress) && item.getLabelName().Equals(label))
                 select item

它将为您创建一个包含所有已排序数据的新数组列表

【讨论】:

    【解决方案3】:
            //Here is just an example of list of array 
           List<object> obj = new List<object>();
            obj.Add(5);
            obj.Add(4);
            obj.Add("we");
            obj.Add(5);
            List<object> objTodelete = new List<object>();
    
            foreach (var item in obj)
            {
                int count = obj.Count(a => a.ToString() == item.ToString());
                //for finding the dublicate occurence
                if (count > 1)
                {
                    //for removing that dublicated occurence.
                    object Dublicate = obj.Find(m => m.ToString() == item.ToString());
                    if (!objTodelete.Contains(Dublicate))
                    {
                        objTodelete.Add(Dublicate); 
                    }
                }
            }
            foreach (var itemDublicate in objTodelete)
            {
                obj.Remove(itemDublicate);
            }
    

    【讨论】:

    • 先循环for发生,然后找到发生的索引,然后删除。
    • 为什么要先检查有没有Count的对象,如果有再查询呢?你可以只检查var item = obj.FirstOrDefault(a =&gt; a.ToString() == item.ToString());,然后你可以检查if (item != null) {obj.Remove(item);
    • 它会导致与作者的'System.InvalidOperationException'相同的异常。在遍历对象期间无法修改对象
    • 感谢您的回答,现在知道了。
    • 是的,你说得对!对于第一个循环,将重复项添加到另一个列表中,然后从主列表中删除另一个列表。或者您可以使用 for 循环而不是 Foreach。这不会抛出“System.InvalidOperationException”。
    猜你喜欢
    • 1970-01-01
    • 2018-05-29
    • 2020-12-17
    • 2011-11-24
    • 2016-07-08
    • 2015-12-12
    • 1970-01-01
    • 2013-12-24
    • 2015-08-25
    相关资源
    最近更新 更多