0

コレクションの最初の列挙は学年に基づいているため、最初にオブジェクトを年ごとにグループ化する必要があります。 . 次に、日付を月ごとにグループ化する必要があります。(月も現在の日付から逆方向に実行する必要があります。次に、月のグループ内のすべての日付を、最新のものから最も古いものへと降順に並べ替える必要があります。

だから私はこれを行うための最良の方法について自分自身と議論しています.私は毎年、辞書のコレクションの価値を示す学年のキーを持つという考えに惹かれています.月のキー、次にカレンダー イベント オブジェクトのコレクションです。

すなわち。dictionary<string, dictionary<string, List<CalendarEvent>>

この方法に関する私の 1 つの懸念は、タイムラインの最初のオブジェクトが最新であるタイムラインを作成するためにオブジェクトが使用されるため、並べ替えと正しい順序が維持されることです。(Facebook のタイムラインを例にとると、Facebook のイベントは年、月、週などでグループ化されます)。

上記のコレクションは最高ですか、それとも私が考えていなかった可能性のある、より簡単な解決策またはパスがありますか?

このコレクションは MVC ビューに渡されるため、ビューでのコレクションのマッサージが少ないほど良いため、 List の道をたどっていません。日付も 9 月にまたがる学年度ごとにグループ化されています。 - June 、したがって学年度の文字列 '201213'。したがって、私の意図は、コレクションを 1 回ループすることです。

ディクショナリを 1 回ループし、ディクショナリ内の各項目について月の内部ディクショナリを再度ループし、実際のカレンダー オブジェクトを再度ループして、タイム ラインのイベントの時系列降順を提供します。

イベントの降臨とともに

つまり...

2013年

7月

-- イベント 1 7 月 10 日

-- イベント 2 7 月 1 日

六月

-- イベント×6月30日

-- イベント foo 6 月 1 日

2012年

4月

-- 4月1日のイベントバー

4

5 に答える 5

2

問題を複雑にしすぎているように思えます。数年分のデータについて話しているだけの場合は、次の 2 次元配列を使用できますList<CalendarEvent>

const int NumYears = 100;
const int BaseYear = 2012;
List<CalendarEvent>[,] MyEvents = new List<CalendarEvent>[NumYears, 12];

したがって、2014 年 1 月のリストを取得するには、次のように記述します。

List<CalendarEvent> jan2014 = MyEvents[2014 - BaseYear, 0];

これは多くのスペースを占有せず、非常に簡単に操作できます。配列自体は100*12*(sizeof IntPtr)バイトしか取りません。つまり、32 ビット マシンで約 4,800 バイト、64 ビット マシンで約 9,600 バイトです。もちろん、割り当てる各リストにはより多くのスペースが必要ですが、特定の月にイベントがない場合は、その費用を支払う必要はありません。また、ほとんどの月にイベントがある場合、これは辞書よりもはるかに少ないスペースで済みます。

学年度が 9 月から 6 月までで、スペースが心配な場合は、2 番目のランクに 10 個の要素のみを持たせ、月/年 (たとえば 2014 年 1 月) を適切なインデックスに変換するメソッドを使用できます (これは、 2013 年度の 4 番目の月になります)。多分気にしないだろうけど。100 年分のデータに対して 200 個の null 参照しか話していません。特別な条件を表現するには、おそらくそれ以上の量のコードが必要になるでしょう。

個々のイベントに関する限り、特定の月にはおそらくそれほど多くはないので、それらを時系列に並べようとしてもあまり意味がありません。OrderByそれらを列挙する時が来たら、リストを日付でソートするだけです。その少数のイベントの並べ替えには、それほど時間はかかりません。

IEnumerable<CalendarEvent>適切な列挙順序を実装して保証するクラスにすべてをラップするのは非常に簡単です。

もう 1 つのオプションは、単純なList<CalendarEvent>ものをバッキング ストアとして使用し、イベントを任意の順序でスローすることです。次に、特定の学年度または年の範囲 (または単一の月または日付) のすべてのイベントを表示する場合は、LINQ の選択と並べ替え (降順) を使用して、必要なものを選択できます。それは、実際に作業しているイベントの数、合計数、およびそれをマッサージする必要がある頻度によって異なります. イベントの総数が数千、場合によっては数万の場合、選択と並べ替えには数ミリ秒かかります。これは、数が私が推測するほど小さい場合、おそらく私が行く方法です。

于 2013-07-11T22:16:20.267 に答える
0

実装と保守が簡単なこのソリューションを試してみてください。使う :

SortedDictionary<YearMonth, Event>

YearMonth クラスは IComparable を実装する必要があり、年と月が降順であることを指定できます。

乾杯

于 2013-07-11T21:50:48.267 に答える
0

すべてのイベントには、それぞれ適切な日付とイベントの説明を作成する日付があるため、簡単に表示できるように、カレンダーイベントクラスと月の列挙型を作成しました。

    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);
                }
            }
于 2013-07-12T03:10:04.767 に答える
0

辞書が特定の順序で列挙されることは保証されていません。SortedList または SortedDictionary コレクションのツリーは、おそらくあなたがしようとしていることを実行します。

おそらく、IComparable をサポートするコレクション (List など) を使用する必要があります。

于 2013-07-11T21:45:00.390 に答える
0

時間によってキー設定されたポイントを持つ範囲ツリーは、おそらくより良いアイデアです。それらについての役立つスライドを次に示します。

ツリーが気にするのは正確な時間だけなので、レンジ ツリーを使用すると、ハウスキーピングが大幅に少なくて済みます。これは、月や年などの人間の構成要素とは無関係です。これは、人間の構成要素が恐ろしいものであるため、素晴らしいことです (たとえば、月は実際にはタイム ゾーンによってさまざまな時間に終了します)。人間のことは、クエリする範囲を決定するときにのみ登場します。

于 2013-07-11T21:45:24.987 に答える