Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LINQ Select Records X Minutes apart

Tags:

c#

sql

linq

I have a simple table that keeps track of the entry date. I would like to select records that are X minutes apart.

IMAGE_LOCATION  IMAGE DATE
============== =============
2227.jpg    08/03/2014 22:27:47
2228.jpg    08/03/2014 22:28:48
2229.jpg    08/03/2014 22:59:49
2230.jpg    08/03/2014 23:12:50
2231.jpg    08/03/2014 23:29:49

From the sample above i would like the query to return items that are at least X minutes apart, lets say 30 min. so from the list above 2227.jpg, 2229.jpg and 2231.jpg would be returned only.

This is what i have so far that just returns the latest images, however i need the latest ones but separated by at least 30 minutes between records.

using (var db = new GibFrontierEntities())
{
    var result = (from u in db.CCTV_IMAGES.OrderByDescending(u => u.ImageDate)
                  select u).Take(rows);
    return result.ToList();
}
like image 848
Tommy Avatar asked Nov 23 '22 01:11

Tommy


1 Answers

This is a quick attempt to achieve exactly what you asked for, a LINQ solution (tested and working in .NET 4):

var list = db.CCTV_IMAGES.OrderByDescending(u => u.ImageDate);
return list.Where((d, i) =>
        {
            //Look ahead to compare against the next if it exists.
            if (list.ElementAtOrDefault(i + 1) != null)
            {
                return d.ImageDate.Subtract(list.ElementAtOrDefault(i + 1).ImageDate).TotalMinutes > 30;
            }

            //Look behind to compare against the previous if this is the last item in the list.
            if (list.ElementAtOrDefault(i - 1) != null)
            {
                return list.ElementAtOrDefault(i - 1).ImageDate.Subtract(d.ImageDate).TotalMinutes > 30;
            }

            return false;
        }).ToList();

Per comments and a clearer definition of the requirement:

Because you stated in the comments below that you will have 1 item a minute and you previously stated that you need them separated by at least 30 minutes, would you consider simplifying the logic to grab every 30th item from the list?

return list.Where((d, i) => i % 30 == 0);
like image 164
alan Avatar answered Jun 17 '23 18:06

alan