使用LINQ在数组中查找最小和最大日期?

Posted

技术标签:

【中文标题】使用LINQ在数组中查找最小和最大日期?【英文标题】:Find minimal and maximal date in array using LINQ? 【发布时间】:2011-01-09 02:39:04 【问题描述】:

我有一个属性为Date 的类数组,即:

class Record

    public DateTime Date  get; private set; 


void Summarize(Record[] arr)

    foreach (var r in arr)
    
        // do stuff 
    

我必须在这个数组中找到earliest(最小值)和latest(最大值)日期。

如何使用 LINQ 做到这一点?

【问题讨论】:

“高效”和“最佳”需要上下文。您更喜欢在空间(内存使用、代码大小)或时间(运行时间、编译时间)方面高效的算法? 【参考方案1】:

如果要查找最早或最晚的日期:

DateTime earliest = arr.Min(record => record.Date);
DateTime latest   = arr.Max(record => record.Date);

Enumerable.Min, Enumerable.Max


如果要查找日期最早或最晚的记录:

Record earliest = arr.MinBy(record => record.Date);
Record latest   = arr.MaxBy(record => record.Date);

见:How to use LINQ to select object with minimum or maximum property value

【讨论】:

绝对是最易读的方式。就纯粹的效率而言,这不是最有效的。不过,我怀疑这段代码会成为瓶颈。 @Keith Rousseau:为什么让你认为这不是“最有效的”? @drj:它迭代数组两次。然而,同样的复杂性,常数因子翻了一番。 @Keith Rousseau 等人:小心微优化。仅当您知道这是一个问题时才进行优化。具有可读性/可维护性,直到/除非您知道这是一个问题。在大多数情况下,这个解决方案很好。 @Brian:我并不是说你应该优化这段代码。我只是指出,从纯粹的效率角度来看,它并不是最有效的。【参考方案2】:

没有 LINQ 的老式解决方案:

DateTime minDate = DateTime.MaxValue;
DateTime maxDate = DateTime.MinValue;
foreach (var r in arr) 

    if (minDate > r.Date)
    
        minDate = r.Date;
    
    if (maxDate < r.Date)
    
        maxDate = r.Date;
    

【讨论】:

好的,对于反对者:原始问题是:with C#,并被编辑为with LINQ 事实上,你搞错了:(minDate > r.Date) 和 (maxDate 【参考方案3】:

二合一 LINQ 查询(和一个遍历):

arr.Aggregate(
    new  MinDate = DateTime.MaxValue,
          MaxDate = DateTime.MinValue ,
    (accDates, record) => 
        new  MinDate = record.Date < accDates.MinDate 
                        ?  record.Date 
                        : accDates.MinDate,
              MaxDate = accDates.MaxDate < record.Date 
                        ?  record.Date 
                        : accDates.MaxDate );

【讨论】:

非常有趣!请你看我的下一个问题***.com/questions/2138391/…如果你能回答我会很高兴,我可以接受。【参考方案4】:

使用 lambda 表达式:

void Summarise(Record[] arr)

    if (!(arr == null || arr.Length == 0))
    
        List<Record> recordList = new List<Record>(arr);
        recordList.Sort((x,y) =>  return x.Date.CompareTo(y.Date); );

        // I may have this the wrong way round, but you get the idea.
        DateTime earliest = recordList[0];
        DateTime latest = recordList[recordList.Count];
    

基本上:

按日期排序到新列表中 选择该列表的第一个和最后一个元素

更新:考虑一下,如果您完全关心性能,我不确定这是否是这样做的方法,因为对整个列表进行排序将导致更多的比较,而不仅仅是扫描最高/最低值。

【讨论】:

【参考方案5】:

我只需创建两个属性 Min,Max,将您添加到数组中的第一项的值分配给它们,然后每次添加新项时只需检查其 DateTime 是否小于或大于 Min Max 的值.

它既好又快,并且比每次需要获取 Min Max 时遍历数组要快得多。

【讨论】:

以上是关于使用LINQ在数组中查找最小和最大日期?的主要内容,如果未能解决你的问题,请参考以下文章

从 PySpark 中的 RDD 中的数据中查找最小和最大日期

在 Java 中使用数组查找最小值、最大值和平均值

使用分治法是不是会提高在数组中查找最大值和最小值的时间复杂度

在数组中查找最大和最小数

查找每个 ID 的特定日期之前的最大日期和特定日期之后的最小日期 [关闭]

从 pandas 的时间序列范围中查找最小和最大日期