0

I have a C# list of a model.

List<FooModel> myModel;

public class FooModel {
    public int CreationTimeInMs;
}

My list is already sorted by CreationTimeInMs (DSC) and I would like to get a part of that list up to last 30 days. For example: If I have 1000 items in the list and the CreationTimeInMs goes back 2 months, I would like to a list of only the last 30 days.

What's the approach ?

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
Alon
  • 3,734
  • 10
  • 45
  • 64

2 Answers2

2

30 Days means 1000 * 60 * 60 * 24 * 30 = 2.592.000.000ms

Use this in a simple Lambda expression to filter out the newest Models. Note that you need to know your "actual time".

UInt64 ActualTime = 12345; //Define the actual time in ms here
IEnumerable <myModel> NewestModels = myModel.Where(x => ActualTime - (Convert.ToUInt64(x.CreationTimeInMs)) > 2592000000);

Now your NewestModels contains all the Models you need.

Fruchtzwerg
  • 10,999
  • 12
  • 40
  • 49
1

A solution is the following:

long nowTimestamp = <compute now timestamp>;
long delta = 30 * 24 * 60 * 60 * 1000;        // ms
var result = myModel.Where(item => nowTimestamp - item.CreationTimeInMs > delta);

However, this approach has a linear complexity (O(list_length)) and does not use the fact that it is sorted.

If the list is sorted descending you can just construct another list, as long as current timestamp is new enough:

var recentList = new List<FooModel>();
foreach (var item in myModel)
{
    if (nowTimestamp - item.CreationTimeInMs > delta)
        break;

    recentList.Add(item);
}

This is the fastest approach, but requires the list to be ordered in a descending manner.

If the list comes in a ascending order, you must first find the item that is the last to be included. As already mentioned, the fastest way is to use a binary search approach, as indicated in this question.

Using provided index, you can get all subsequent elements:

int indexOfFirstElement = myModel.BinarySearchForMatch(item => item.CreationTimeInMs > nowTimestamp - delta);

var recentList = new List<FooModel>();
for (int i = indexOfFirstElement; i < myModel.Count; i ++)
{
    recentList.Add(myModel[i]);
} 

Binary search takes O(log(list_size)) and list construction is O(result_size).

Community
  • 1
  • 1
Alexei - check Codidact
  • 22,016
  • 16
  • 145
  • 164