迭代自定义对象集合并删除重复项

时间:2014-12-01 05:56:28

标签: c# loops

我有自定义集合类,它包含特定的自定义对象。对象类称为TestReport,包含这些对象的集合类称为TestReports,它继承System.Collections.CollectionBaseTestReport包含属性LocalReportIDScoreTypeID。我想要做的是遍历对象集合并删除任何重复项,在我的情况下,这意味着对象之间的ScoreTypeIDLocalReportID是相同的。到目前为止我所遗漏的物品并没有正确地完成工作,我对解决方案感到非常难过。请注意,每次重复时,我都会将对象放在另一个集合中,然后再删除重复项。我不打算这样做,这只是我的想法,但如果有更好的方法来完成它,请告诉我:

TestReports objTestReportsContainer = new TestReports();
foreach (TestReport objTestReport in objTestReports)
{
    objTestReportsContainer.Add(objTestReport);
}
objTestReports.Clear();

for (int i = 0; i < objTestReportsContainer.Count - 1; i++)
{
    for (int k = objTestReportsContainer.Count - 1; k > 0; k--)
    {
        if ((objTestReportsContainer.Item(k).LocalReportID == objTestReportsContainer.Item(i).LocalReportID) &&
            (objTestReportsContainer.Item(k).ScoreTypeID == objTestReportsContainer.Item(i).ScoreTypeID) &&
            (objTestReportsContainer.Item(k).LocalReportID != 0))
            {
                objTestReports.Add(objTestReportsContainer.Item(k));
                objTestReportsContainer.Remove(objTestReportsContainer.Item(i));
                objTestReportsContainer.Remove(objTestReportsContainer.Item(k));
            }
            else if ((objTestReportsContainer.Item(k).ScoreTypeID == objTestReportsContainer.Item(i).ScoreTypeID) &&
                     (objTestReportsContainer.Item(k).LocalReportID == 0) && 
                     (objTestReportsContainer.Item(i).LocalReportID == 0))
            {
                objTestReports.Add(objTestReportsContainer.Item(k));
                objTestReportsContainer.Remove(objTestReportsContainer.Item(i));
                objTestReportsContainer.Remove(objTestReportsContainer.Item(k));
            }
     }
}

原始项目填充在objTestReports中,然后我将其移至objTestReportsContainer,以便我可以完成该集合的所有工作,并将最终过滤的集合添加回objTestReports。这段代码似乎每次都留下一些项目,我找不到解决方案。有没有更好的方法来解决这个问题?

编辑我忘了注意在if语句中我将LocalReportID是否为0分开,因为如果它是TestReport对象则被视为平均报告,如果它不是0它的乐队报道。只是为了澄清,但对于迭代流应该如何工作可能并不重要。

编辑2 根据我的要求TestReports。模式UIGetLocalTestReports就是我用TestReport个主题填充集合的内容。

public class TestReports : System.Collections.CollectionBase
{
    public TestReports()
    {
        //constructor?
        List.Clear();
    }

    public void Add(TestReport objTestReport)
    {
        // add a testReport to the testReports collection
        List.Add(objTestReport);
    }

    public void Remove(int index)
    {
        // remove a testReport from the testReports collection
        if (index <= Count - 1 && index >= 0)
        {
            List.RemoveAt(index);
        }
    }

    public void Remove(TestReport objTestReport)
    {
        //remove a TestReport from the collection without passing an index
        List.Remove(objTestReport);
    }

    public TestReport Item(int Index)
    {
        //get the item requested and explicitly cast to the testSubject type
        return (TestReport)List[Index];
    }

    public void UIGetLocalTestReports(SqlConnection mySqlConn, int intTestTypeID)
    {
        //clear list
        List.Clear();

        if (mySqlConn.State == ConnectionState.Open)
        {
            SqlCommand myComm = new SqlCommand("StatsGen_UI_ByTest_GetReports", mySqlConn);
            myComm.CommandType = CommandType.StoredProcedure;
            myComm.Parameters.Add(new SqlParameter("@intTestTypeID", intTestTypeID));
            try
            {
                SqlDataReader dr = myComm.ExecuteReader();
                if (dr.HasRows)
                {
                    TestReport objTestReport;
                    while (dr.Read())
                    {
                        objTestReport = new TestReport();
                        objTestReport.TestReportID = dr.GetInt32(0);
                        objTestReport.TestReportName = dr.GetString(1);
                        objTestReport.SummaryDataSP = dr.GetString(2);
                        objTestReport.ScoreTypeID = dr.GetInt32(3);
                        if (dr.GetValue(4) != DBNull.Value)
                            objTestReport.LocalReportID = dr.GetInt32(4);
                        else
                            objTestReport.LocalReportID = 0;
                        List.Add(objTestReport);
                    }
                }
                dr.Close();
            }
            catch (SqlException)
            {
                //TODO: Add some error handling here.
            }
        }
    }
} 

2 个答案:

答案 0 :(得分:1)

让我知道这段代码是否让你更接近:

var keepers =
    objTestReports
        .Cast<TestReport>()
        .GroupBy(x => new { x.LocalReportID, x.ScoreTypeID })
        .SelectMany(x => x.Take(1))
        .ToArray();

objTestReports.Clear();

foreach (var objTestReport in keepers)
{
    objTestReports.Add(objTestReport);
}

答案 1 :(得分:0)

您可以致电objTestReports.OfType<TestReport>()获取IEnumerable<TestReport>并继续使用LINQ。

您可以使用Distinct扩展方法获取不同的项目。

IEnumerable<TestReport> reportsAsEnumerable = objTestReports.OfType<TestReport>().Distinct();

如果TestReport没有实现IEquatable,你应该实现它,或者使用自定义IEqualityComparer(参见http://msdn.microsoft.com/en-us/library/bb338049(v=vs.110).aspx