C# 词典词典是这里最好的解决方案吗?

C# 词典词典是这里最好的解决方案吗?,c#,collections,C#,Collections,我有一组日历事件对象,其日期值跨越若干学年,如201213、201112等 我需要首先按年份对对象进行分组,因为集合的第一次枚举是基于学年的。然后我需要将日期按月份分组。(月份也需要从当前日期向后运行。然后,月份分组中的每个日期都需要从最晚的日期到最早的日期进行排序 因此,我正在与自己讨论最好的方法,我被这样的想法所吸引,每年都有一个学年的索引,它指向一组字典的价值,这些字典又有一个月的索引,然后是一组日历事件对象 例如,dictionary字典不保证按任何特定顺序枚举。SortedList或S

我有一组日历事件对象,其日期值跨越若干学年,如201213、201112等 我需要首先按年份对对象进行分组,因为集合的第一次枚举是基于学年的。然后我需要将日期按月份分组。(月份也需要从当前日期向后运行。然后,月份分组中的每个日期都需要从最晚的日期到最早的日期进行排序

因此,我正在与自己讨论最好的方法,我被这样的想法所吸引,每年都有一个学年的索引,它指向一组字典的价值,这些字典又有一个月的索引,然后是一组日历事件对象


例如,
dictionary字典不保证按任何特定顺序枚举。SortedList或SortedDictionary集合的树可能会执行您尝试执行的操作

也许你应该使用一个支持IComparable的集合(比如List)。

a,用时间键控点,可能是一个更好的主意。下面介绍一下它们


范围树需要更少的内务管理,因为它唯一关心的是准确的时间。它独立于人类构造,如月和年,这很好,因为人类构造是可怕的事情(例如,由于时区的不同,月实际上在许多不同的时间结束)。只有在决定要查询的范围时,才会考虑到人的因素。

您应该尝试此解决方案,它易于实施和维护;使用:

SortedDictionary<YearMonth, Event>
SortedDictionary
YearMonth类应该实现IComparable,您可以在其中指定年份和月份的降序


干杯

在我看来,你似乎把问题复杂化了。如果你只是在谈论几年的数据,你可以使用一个二维数组
列表

const int NumYears=100;
const int BaseYear=2012;
列表[,]MyEvents=新列表[NumYears,12];
因此,要获得2014年1月的名单,您可以写:

List<CalendarEvent> jan2014 = MyEvents[2014 - BaseYear, 0];
List jan2014=MyEvents[2014-基准年,0];
这不会占用很多空间,而且使用起来非常简单。数组本身只需要
100*12*(sizeof IntPtr)
bytes。因此,32位机器上大约4800字节,64位机器上大约9600字节。您分配的每个列表当然需要更多的空间,但如果特定月份没有事件,则您无需支付该费用。如果大多数月份都有事件,则占用的空间将比字典少得多

如果你的学年是9月到6月,并且你担心空间,你可以让第二个排名只有10个元素,并且有方法将你的月/年(比如2014年1月)转换为适当的指数(我假设是2013学年的第4个月).不过我可能不会担心。我们只讨论了100年数据的200个空引用。可能需要更多的代码来表示特殊条件

就单个事件而言,一个月内可能不会有太多事件,因此尝试按时间顺序对其进行排序是没有意义的。只需在列表上按日期进行排序,就可以在枚举事件时对其进行排序。对少量事件进行排序不会占用任何可观的时间

将这一切封装在一个类中应该很容易,该类实现了
IEnumerable
,并保证了正确的枚举顺序


另一种选择是使用一个简单的
列表
作为后备存储,只需按任意顺序将事件放入其中。然后,如果要显示特定学年或年份范围(甚至是单个月或日期)的所有事件,可以使用LINQ select和order by(降序?)选择你想要的。这实际上取决于你处理的事件总数,以及你需要按摩的频率。如果事件总数在数千甚至数万,选择和排序将花费毫秒。如果数字像我一样小,我可能会这样做怀疑他们是。

因为每个事件都有一个日期,每个日期都有一个合适的日期和事件描述,所以我制作了一个calendarevent类和月枚举,以便于显示:

    public enum NameOfMonth
    {
        january = 1,
        febuary,
        march,
        april,
        may,
        june,
        july,
        august,
        september,
        october,
        november,
        december
    }

    class CalendarEvent
    {
        public NameOfMonth month;
        public DateTime date { get; set; }
        public string eventdescription { get; set; }

        public CalendarEvent()
        {

        }
    }
然后,使用每个calendarevent对象创建一个列表(当然每个对象都有一个描述、日期等…),然后按年份对其进行分组创建一个匿名对象,并按月份排序,然后按天排序,然后仅显示它们:

            List<CalendarEvent> myevents = new List<CalendarEvent>()
            {
                new CalendarEvent(){date = new DateTime(2005,1,17),eventdescription = "Armaggedon",month = NameOfMonth.january},
                new CalendarEvent(){date =  new DateTime(2005,3,20),eventdescription = "Apocalypse",month = NameOfMonth.march},
                new CalendarEvent(){date = new DateTime(2007,5,20),eventdescription = "WorldPeace",month = NameOfMonth.may},
                new CalendarEvent(){date = new DateTime(2009,2,20),eventdescription = "LaundryDay",month = NameOfMonth.febuary},
                new CalendarEvent(){date = new DateTime(2009,4,15),eventdescription = "MentalHealth",month = NameOfMonth.april},
                new CalendarEvent(){date = new DateTime(2009,6,10),eventdescription = "ProgrammingInC#",month = NameOfMonth.june},
                new CalendarEvent(){date = new DateTime(2009,6,12),eventdescription = "EraseAllYourWork?",month = NameOfMonth.june},
                new CalendarEvent(){date = new DateTime(2010,10,20),eventdescription = "SomeVeryNiceEvent",month = NameOfMonth.october},
                new CalendarEvent(){date = new DateTime(2010,8,21),eventdescription = "WellAnotherEvent",month = NameOfMonth.august}
            };
            var result = myevents2.GroupBy(d => d.date.Year)
                      .Select(g => new { Year = g.Key, data = g.OrderByDescending(k => k.date.Month).ThenByDescending(day => day.date.Day) })
                      .ToList();

            foreach (var item in result)
            {
                Console.WriteLine("Events on ***" + item.Year + "***");
                foreach (var subitems in item.data)
                {  
                    Console.WriteLine(subitems.month.ToString());
                    Console.WriteLine("On day " + subitems.date.Day + " - " + subitems.eventdescription);
                }
            }
List myevents=new List()
{
new CalendarEvent(){date=new DateTime(2005,1,17),eventdescription=“Armaggedon”,month=NameOfMonth.january},
new CalendarEvent(){date=new DateTime(2005,3,20),eventdescription=“启示录”,month=NameOfMonth.march},
new CalendarEvent(){date=new DateTime(2007,5,20),eventdescription=“WorldPeace”,month=NameOfMonth.may},
new CalendarEvent(){date=new DateTime(2009,2,20),eventdescription=“LaundryDay”,month=NameOfMonth.febuary},
new CalendarEvent(){date=new DateTime(2009,4,15),eventdescription=“MentalHealth”,month=NameOfMonth.april},
new CalendarEvent(){date=new DateTime(2009,6,10),eventdescription=“ProgrammingInC#”,month=NameOfMonth.june},
new CalendarEvent(){date=new DateTime(2009,6,12),eventdescription=“EraseAllYourWork?”,month=NameOfMonth.june},
new CalendarEvent(){date=new DateTime(2010,10,20),eventdescription=“SomeVeryNiceEvent”,month=NameOfMonth.十月},
new CalendarEvent(){date=new DateTime(2010,8,21),eventdescription=“WellAno
            List<CalendarEvent> myevents = new List<CalendarEvent>()
            {
                new CalendarEvent(){date = new DateTime(2005,1,17),eventdescription = "Armaggedon",month = NameOfMonth.january},
                new CalendarEvent(){date =  new DateTime(2005,3,20),eventdescription = "Apocalypse",month = NameOfMonth.march},
                new CalendarEvent(){date = new DateTime(2007,5,20),eventdescription = "WorldPeace",month = NameOfMonth.may},
                new CalendarEvent(){date = new DateTime(2009,2,20),eventdescription = "LaundryDay",month = NameOfMonth.febuary},
                new CalendarEvent(){date = new DateTime(2009,4,15),eventdescription = "MentalHealth",month = NameOfMonth.april},
                new CalendarEvent(){date = new DateTime(2009,6,10),eventdescription = "ProgrammingInC#",month = NameOfMonth.june},
                new CalendarEvent(){date = new DateTime(2009,6,12),eventdescription = "EraseAllYourWork?",month = NameOfMonth.june},
                new CalendarEvent(){date = new DateTime(2010,10,20),eventdescription = "SomeVeryNiceEvent",month = NameOfMonth.october},
                new CalendarEvent(){date = new DateTime(2010,8,21),eventdescription = "WellAnotherEvent",month = NameOfMonth.august}
            };
            var result = myevents2.GroupBy(d => d.date.Year)
                      .Select(g => new { Year = g.Key, data = g.OrderByDescending(k => k.date.Month).ThenByDescending(day => day.date.Day) })
                      .ToList();

            foreach (var item in result)
            {
                Console.WriteLine("Events on ***" + item.Year + "***");
                foreach (var subitems in item.data)
                {  
                    Console.WriteLine(subitems.month.ToString());
                    Console.WriteLine("On day " + subitems.date.Day + " - " + subitems.eventdescription);
                }
            }