【问题标题】:How to return a part of a list using creation time?如何使用创建时间返回列表的一部分?
【发布时间】:2016-03-27 08:02:20
【问题描述】:

我有一个模型的 C# 列表。

List<FooModel> myModel;

public class FooModel {
    public int CreationTimeInMs;
}

我的列表已按 CreationTimeInMs (DSC) 排序,我希望获得该列表的一部分,直到最近 30 天。 例如: 如果列表中有 1000 个项目,CreationTimeInMs 可以追溯到 2 个月,我想要一个仅包含过去 30 天的列表。

方法是什么?

【问题讨论】:

  • 有什么理由将其存储为字符串?
  • @TahTatsumoto,它从第 3 方 API 以整数形式返回

标签: c# .net


【解决方案1】:

30 天意味着 1000 * 60 * 60 * 24 * 30 = 2.592.000.000ms

在一个简单的 Lambda 表达式中使用它来过滤出最新的模型。请注意,您需要知道您的“实际时间”。

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

现在您的 NewestModels 包含您需要的所有模型。

【讨论】:

  • 如何计算现在的毫秒数?
  • 这取决于您的第 3 方工具使用的时间格式。你有更多关于时间格式的信息吗?
【解决方案2】:

解决方案如下:

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

但是,这种方法具有线性复杂度 (O(list_length)),并且没有使用已排序的事实。

如果列表按降序排序,只要当前时间戳足够新,您就可以构建另一个列表:

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

    recentList.Add(item);
}

这是最快的方法,但要求列表按降序排列。

如果列表按升序排列,您必须首先找到最后包含的项目。如前所述,最快的方法是使用二分查找方法,如this question 所示。

使用提供的索引,可以获取所有后续元素:

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]);
} 

二分查找需要 O(log(list_size)) 并且列表构造是 O(result_size)。

【讨论】:

  • 现在是整数,不是字符串
猜你喜欢
  • 2015-01-20
  • 1970-01-01
  • 2020-04-16
  • 1970-01-01
  • 2021-12-16
  • 2017-07-19
  • 1970-01-01
  • 2020-08-15
  • 1970-01-01
相关资源
最近更新 更多