HitTheSky HitTheSky - 1 month ago 11
C# Question

Need to combine two collections and retaining sort order of each collection

I need to combine two different collections and display them together, the problem am facing is, retaining the collections original sort order.

class Program
{
static void Main(string[] args)
{
var NewsList = new List<DateTime>();
NewsList.Add(new DateTime(2016, 9, 25));
NewsList.Add(new DateTime(2016, 10, 15));
NewsList.Add(new DateTime(2016, 10, 24));
NewsList.Add(new DateTime(2016, 10, 27));
NewsList.Add(new DateTime(2016, 10, 31));

var EventList = new List<DateTime>();
EventList.Add(new DateTime(2016, 10, 31));
EventList.Add(new DateTime(2016, 11, 1));
EventList.Add(new DateTime(2016, 11, 4));
EventList.Add(new DateTime(2016, 11, 5));
EventList.Add(new DateTime(2016, 11, 10));

var CombinedList = EventList.Union(NewsList).OrderBy(i => i);

Display(SortDescending(NewsList), "News List SortDescending - Newsest To Oldest");
Display(SortAscending(EventList), "Event List SortAscending - Oldest To Newest");
DisplayCombined(CombinedList, "ComindedList");

}

/// Displays the list from Oldest -> Newest
static List<DateTime> SortAscending(List<DateTime> list)
{
list.Sort((a, b) => a.CompareTo(b));
return list;
}

/// Displays the list from Newest -> Oldest
static List<DateTime> SortDescending(List<DateTime> list)
{
list.Sort((a, b) => b.CompareTo(a));
return list;
}

static void Display(List<DateTime> list, string message)
{
Console.WriteLine(message);
foreach (var datetime in list)
{
Console.WriteLine(datetime);
}
Console.WriteLine();
Console.ReadLine();
}

static void DisplayCombined(IEnumerable<DateTime> list, string message)
{
Console.WriteLine(message);
foreach (var datetime in list)
{
Console.WriteLine(datetime);
}
Console.WriteLine();
Console.ReadLine();
}
}


As you will see above I've attempted to use a union which combines the two lists but the problem being that it displays both collection based on the sort order set on the combined list

What I'd like to display would be a staggered list displayed, so I am getting one item from one list then the next etc etc.... as such

EventList.Add(new DateTime(2016, 10, 31)) - First Event
NewsList.Add(new DateTime(2016, 9, 25)); - First News Item
EventList.Add(new DateTime(2016, 11, 1)); - Second Event
NewsList.Add(new DateTime(2016, 10, 15)); - Second News Item
EventList.Add(new DateTime(2016, 11, 4)); - Third Event Item
NewsList.Add(new DateTime(2016, 10, 24)); - Third News Item

Answer

You could make your CombinedList contain classes that contain two values, the event date and the news date. For example:

var combinedList = NewsList.Zip(NewsList, 
    (first, second) => { return new {EventDate = first, NewsDate = second}; });
int i = 1;
foreach (var x in combinedList)
{
    Console.WriteLine($"Event {i}: {x.EventDate}");
    Console.WriteLine($"News {i}: {x.NewsDate}");
    ++i;
}

This assumes that the EventList and NewsList have the same number of items. If one is longer than the other, then those additional items will be lost.

Comments