如何从嵌套的C#列表中删除重复的值

本文关键字:删除 嵌套 列表 | 更新日期: 2023-09-27 18:00:12

我有一个如下的模型设置:

public class ReportScheduleModel
{
    public string Day { get; set; }
    public List<ReportTimes> reportTimes { get; set; }
}
public class ReportTimes
{
    public byte hourOfDay { get; set; }
    public byte minuteOfDay { get; set; }
    public string reportType { get; set; }
}

然后,我可以用以下列表格式将整个列表传回我的控制器:

List<ReportScheduleModel> ReportSchedule
    [0]->Day: 'Sunday'
         [ReportTimes]: [0]->hourOfDay: '09'
                        minuteOfDay: '23'
                        reportType: 'Test1'
                   [1]->hourOfDay: '08'
                        minuteOfDay: '11'
                        reportType: 'Test2'
    [1]->Day: 'Sunday'
         [ReportTimes]: [0]->hourOfDay: '09'
                        minuteOfDay: '23'
                        reportType: 'Test1'
                        [1]->hourOfDay: '11'
                        minuteOfDay: '30'
                        reportType: 'Test1'
    [2]->Day: 'Monday'
         [ReportTimes]: [0]->hourOfDay: '09'
                        minuteOfDay: '23'
                        reportType: 'Test1'

在上面的列表中,您注意到ReportSchedule[0]ReportSchedule[1]的报告时间都完全相同,列为"09:23 Test1"。我想做的是找到一个没有这些重复值的列表,它只保留一个重复的报告时间值。因此,基于以上内容,我理想的过滤列表是:(Day不分组/唯一并不重要,只是基于同一天的ReportTimes

    [0]->Day: 'Sunday'
             [ReportTimes]: [0]->hourOfDay: '09'
                            minuteOfDay: '23'
                            reportType: 'Test1'
                       [1]->hourOfDay: '08'
                            minuteOfDay: '11'
                            reportType: 'Test2'
        [1]->Day: 'Sunday'
             [ReportTimes]: [0]->hourOfDay: '11'
                            minuteOfDay: '30'
                            reportType: 'Test1'
        [2]->Day: 'Monday'
             [ReportTimes]: [0]->hourOfDay: '09'
                            minuteOfDay: '23'
                            reportType: 'Test1'

如何从嵌套的C#列表中删除重复的值

重要请确保您的ReportTimes类以合理的方式实现GetHashCode和Equals:即,相同的条目总是散列为相同的值,不同的时间条目散列为不同的值。

然后,您可以为每天创建一个HashSet数据结构,并线性遍历嵌套列表,每天将所有列表中的所有报告时间添加到适当的集合中。

以上内容将确保每天只保留唯一的ReportTimes实例。在ReportTimes实例的数量上,它将具有线性时间性能!

当然,您也可以重复使用哈希集,一次只做一天。。

var sets  = new Dictionary<string, HashSet<ReportTimes>>();
// assuming ReportSchedule is the list of ReportScheduleModel items
foreach(var scheduleItem in ReportSchedule)
{
     if(!sets.ContainsKey(scheduleItem.Day))
        sets.Add(scheduleItem.Day, new HashSet<ReportTimes>());
     foreach(var rt in scheduleItem.reportTimes)
     {
          sets[scheduleItem.Day].Add(rt);
     }
}
// at this point, each set in the sets dictionary will contain only unique items
// if you wanted to get all the unique report times for Sunday you would use something like:
foreach(var rt in sets["Sunday"])
{
    Console.WriteLine("{0}:{1} - {2}", rt.hourOfDay, rt.minuteOfDay, rt.reportType);
}

我希望上面的例子足够清楚。正如我在开头所说的,请确保在ReportTime类中实现GetHashCode和Equals。这里有一个例子:

public class ReportTimes
{
    public byte hourOfDay { get; set; }
    public byte minuteOfDay { get; set; }
    public string reportType { get; set; }
    public override int GetHashCode()
    {            
        return reportType.GetHashCode ^ (hourOfDay << 8) ^ (minuteOfDay);
    }
    public override bool Equals(object other)
    {
        if(other is ReportTimes)
        {
            var ort = (ReportTimes)other;
            // returns true if the 'other' object represents the same time & type
            return    ort.hourOfDay.Equals(hourOfDay);
                   && ort.minuteOfDay.Equals(minuteOfDay);
                   && ort.reportType.Equals(reportType);
        }
        return false;  // if comparing to a non-ReportTimes object always return false
    }
}