Tomasz Kowalczyk
Tomasz Kowalczyk

Reputation: 1923

TimeSpan difference between elements in List

I have a List with following objects:

public class DomainTimeErrors
{
    public int DomainId { get; set; }
    public int JobId { get; set; }
    public DateTime? FinishedAt { get; set; }
    public string Domain { get; set; }
    public string Url { get; set; }
}

How to get those objects with the same value in Url property where TimeSpan between values in FinishedAt is more then 1 hour.

EDITED:

From the following list:

var list = new List<DomainTimeErrors>
{
new DomainTimeErrors { DomainId = 1, JobId = 1, FinishedAt = "2017-12-01 12:00", Domain = "so.com", Url = "so.com/id=1" },
new DomainTimeErrors { DomainId = 1, JobId = 2, FinishedAt = "2017-12-01 12:55", Domain = "so.com", Url = "so.com/id=1" },
new DomainTimeErrors { DomainId = 1, JobId = 3, FinishedAt = "2017-12-01 13:55", Domain = "so.com", Url = "so.com/id=1" },
new DomainTimeErrors { DomainId = 1, JobId = 4, FinishedAt = "2017-12-01 14:00", Domain = "so.com", Url = "so.com/id=1" },
new DomainTimeErrors { DomainId = 1, JobId = 11, FinishedAt = "2017-12-01 12:00", Domain = "so.com", Url = "so.com/id=2" },
new DomainTimeErrors { DomainId = 1, JobId = 12, FinishedAt = "2017-12-01 12:05", Domain = "so.com", Url = "so.com/id=2" },
new DomainTimeErrors { DomainId = 1, JobId = 13, FinishedAt = "2017-12-01 12:55", Domain = "so.com", Url = "so.com/id=2" },
new DomainTimeErrors { DomainId = 1, JobId = 14, FinishedAt = "2017-12-01 12:56", Domain = "so.com", Url = "so.com/id=2" }
}

I would like to get only one of those where Url = "so.com/id=1" because the time difference between the earliest and the latest is more then 1 hour

Upvotes: 1

Views: 150

Answers (2)

Mazaher Bazari
Mazaher Bazari

Reputation: 421

If you use Linq to Object, I think this linq's query answer your question:

Func<IEnumerable<DomainTimeErrors>, bool> checkdiffrent = (items) =>
{
    var itemsCount=items.Count();
    if (itemsCount == 0 || itemsCount == 1)
      return true;

    var sortedItems=items.OrderBy(a=> a.FinishedAt.Value);
    var firstItem=sortedItems.First();
    var lastItem= sortedItems.Last();
    return (firstItem.FinishedAt- lastItem.FinishedAt).Value.TotalHours > 1;
}

var itemWithFinishDate = DomainTimeErrorsCollection.Where(a=> a.FinishedAt.HasValue).
var result = itemWithFinishDate.GroupBy(i=> i.Url).
                Where(sameUrls => checkdiffrent(sameUrls))
                .SelectMany(a=> a);

Upvotes: 1

MikeT
MikeT

Reputation: 5500

using a Linq query i would expect it to look something like

from a in List
join b in List
  on a.Url equals b.Url
where (b.FinishedAt - a.FinishedAt).TotalHours>=1
select b;

you would then use grouping and selectors to screen out unwanted values

ie

from a in List.Where(i=>i.FinishedAt.HasValue)
join b in List.Where(i=>i.FinishedAt.HasValue)
  on a.Url equals b.Url
where (b.FinishedAt - a.FinishedAt).TotalHours>=1
group b by b.url into g
select g.FirstOrDefault();

EDIT Given your edit i would now expect it to look more like this

from i in List
where i.FinishedAt != null
order by i.FinsihedAt 
group i by i.Url into g
where (g.Last().FinsihedAt -g.First().FinsihedAt ).TotalHours >=1
select g.Last();

Upvotes: 1

Related Questions