Moe Bataineh
Moe Bataineh

Reputation: 1080

Group List by similar dates

I want to know if it is possible to group results I get from my database between 2 dates. For example, I want the ability to group results that were 6 seconds apart from each other so I can display them grouped on the front end.

My end goal is to be able to group results by close dates/time such as 6 seconds apart.

Upvotes: 2

Views: 283

Answers (2)

Moe Bataineh
Moe Bataineh

Reputation: 1080

I have created something to do what I wanted. It may not be the best, but it works. This is what I did:

Dictionary<DateTime, List<UserFeed>> feedGrouped = new Dictionary<DateTime,List<UserFeed>>();

foreach(var item in userFeed.OrderByDescending(I => I.Date))
{
    if(feedGrouped.Count >= 15)
        break;

    if (feedGrouped.Where(i => i.Key <= item.Date.AddSeconds(7)).Any())
    {
        feedGrouped.Where(i => i.Key <= item.Date.AddSeconds(7)).FirstOrDefault().Value.Add(item);
    }
    else
    {
        feedGrouped.Add(item.Date, new List<UserFeed> { item });
    }
}

Upvotes: 1

Servy
Servy

Reputation: 203820

We can use this general helper method that takes a sequence and a predicate that takes each pair of consecutive items and determines if they are in the same group to group your items:

public static IEnumerable<IEnumerable<T>> GroupWhile<T>(
    this IEnumerable<T> source, Func<T, T, bool> predicate)
{
    using (var iterator = source.GetEnumerator())
    {
        if (!iterator.MoveNext())
            yield break;

        List<T> list = new List<T>() { iterator.Current };

        T previous = iterator.Current;

        while (iterator.MoveNext())
        {
            if (predicate(previous, iterator.Current))
            {
                list.Add(iterator.Current);
            }
            else
            {
                yield return list;
                list = new List<T>() { iterator.Current };
            }

            previous = iterator.Current;
        }
        yield return list;
    }
}

Now that we have this it's as simple as:

var query = data.OrderBy(item => item.Date)
    .GroupWhile((prev, next) => 
        (prev.Date - next.Date) <= Timespan.FromSeconds(6));

Upvotes: 5

Related Questions