using System.Globalization;
using System.Collections.Generic;
public static void Main() {
var userActions = new [] {
new UserAction { UserName = "Lisa", Action = CrudAction.Edited, Date = DateTime.ParseExact("2018-05-20 09:46", "yyyy-MM-dd HH:mm", CultureInfo.InvariantCulture)},
new UserAction { UserName = "Tom", Action = CrudAction.Edited, Date = DateTime.ParseExact("2018-05-18 11:18", "yyyy-MM-dd HH:mm", CultureInfo.InvariantCulture)},
new UserAction { UserName = "Tom", Action = CrudAction.Edited, Date = DateTime.ParseExact("2018-05-18 11:18", "yyyy-MM-dd HH:mm", CultureInfo.InvariantCulture)},
new UserAction { UserName = "Tom", Action = CrudAction.Edited, Date = DateTime.ParseExact("2018-05-18 11:18", "yyyy-MM-dd HH:mm", CultureInfo.InvariantCulture)},
new UserAction { UserName = "Tom", Action = CrudAction.Edited, Date = DateTime.ParseExact("2018-05-18 11:16", "yyyy-MM-dd HH:mm", CultureInfo.InvariantCulture)},
new UserAction { UserName = "Tom", Action = CrudAction.Edited, Date = DateTime.ParseExact("2018-05-18 11:15", "yyyy-MM-dd HH:mm", CultureInfo.InvariantCulture)},
new UserAction { UserName = "Tom", Action = CrudAction.Edited, Date = DateTime.ParseExact("2018-05-18 11:15", "yyyy-MM-dd HH:mm", CultureInfo.InvariantCulture)},
new UserAction { UserName = "Tom", Action = CrudAction.Edited, Date = DateTime.ParseExact("2018-05-18 11:15", "yyyy-MM-dd HH:mm", CultureInfo.InvariantCulture)},
new UserAction { UserName = "Tom", Action = CrudAction.Edited, Date = DateTime.ParseExact("2018-05-18 10:12", "yyyy-MM-dd HH:mm", CultureInfo.InvariantCulture)},
new UserAction { UserName = "Lisa", Action = CrudAction.Edited, Date = DateTime.ParseExact("2018-05-16 13:28", "yyyy-MM-dd HH:mm", CultureInfo.InvariantCulture)},
new UserAction { UserName = "Lisa", Action = CrudAction.Posted, Date = DateTime.ParseExact("2018-05-16 13:25", "yyyy-MM-dd HH:mm", CultureInfo.InvariantCulture)},
var distinctActions = userActions
.OrderByDescending(ua => ua.Date)
.Distinct(new UserNameActionAndHourComparer());
foreach (var unique in distinctActions) {
Console.WriteLine(unique.UserName + "\t" + unique.Action.ToString("G") + "\t" + unique.Date.ToLongDateString() + " " + unique.Date.ToLongTimeString());
public class UserNameActionAndHourComparer : IEqualityComparer<UserAction> {
public bool Equals(UserAction left, UserAction right){
if (left == null && right == null) {
if (left == null | right == null) {
if(left.UserName == right.UserName && left.Action == right.Action) {
return left.Date.Date == right.Date.Date && left.Date.Hour == right.Date.Hour;
public int GetHashCode(UserAction ua) {
return ua.UserName.GetHashCode()
^ ua.Action.GetHashCode()
^ new DateTime(ua.Date.Year, ua.Date.Month, ua.Date.Day, ua.Date.Hour, 0, 0).GetHashCode();
public class UserAction {
public int LogId { get; set; }
public string UserName { get; set; }
public CrudAction Action { get; set; }
public DateTime Date{ get; set; }