HitTheSky HitTheSky - 1 month ago 10
C# Question

Combining two collections, retaining the sort order then displaying in staggered format

I need to combine two different collections and display them together in staggered format.

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, this displays the entire combined collection in ascending order as set by the OrderBy method (in this case OrderBy(i => i)). If no order is set explicitly, then by default it will return each item held, first from the EventsList then from the NewsList, whilst maintaining the order originally set for both lists.

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


  • 2016, 10, 31 First Event Item

  • 2016, 9, 25 First News Item

  • 2016, 11, 1 Second Event Item

  • 2016, 10, 15 Second News Item

  • 2016, 11, 4 Third Event Item

  • 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(EventList, 
    (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.