gpt4 book ai didi

c# - 如何使用 "Linq to Objects"将一组连续的日期放在一个组中?

转载 作者:太空狗 更新时间:2023-10-29 18:25:32 26 4
gpt4 key购买 nike

我有一个麻烦的查询要写。我目前正在编写一些讨厌的 for 循环来解决它,但我很想知道 Linq 是否可以为我做这件事。

我有:

struct TheStruct
{
public DateTime date {get; set;} //(time portion will always be 12 am)
public decimal A {get; set;}
public decimal B {get; set;}
}

以及包含这些结构的列表。假设它是这样排序的:

List<TheStruct> orderedList = unorderedList.OrderBy(x => x.date).ToList();

如果将 orderedList 结构日期放在一个集合中,它们将始终在日期上是连续的。也就是说,如果列表中的最晚日期是 2011/01/31,而列表中最早的日期是 2011 年/01/01,那么您会发现该列表将包含 31 个项目,每个日期对应一月。

好的,所以我想做的是对列表项进行分组,这样:

  1. 组中的每个项目必须包含相同的十进制 A 值和相同的十进制 B 值
  2. 如果日期值是有序的,则组中的日期值必须形成一组连续的日期
  3. 如果您将每个组中的项目总和相加,总数将等于原始列表中的项目数(或者您可以说具有特定日期的结构不能属于多个组)<

有哪位Linq高手知道这个怎么做?

谢谢!

最佳答案

您可以使用 GroupAdjacent Extension Method 对序列中的相邻项目进行分组(见下文):

var result = unorderedList
.OrderBy(x => x.date)
.GroupAdjacent((g, x) => x.A == g.Last().A &&
x.B == g.Last().B &&
x.date == g.Last().date.AddDays(1))
.ToList();

示例:

(1,1) 2011-01-01   \
(1,1) 2011-01-02 > Group 1
(1,1) 2011-01-03 __/
(2,1) 2011-01-04 \
(2,1) 2011-01-05 > Group 2
(2,1) 2011-01-06 __/
(1,1) 2011-01-07 \
(1,1) 2011-01-08 > Group 3
(1,1) 2011-01-09 __/
(1,1) 2011-02-01   \
(1,1) 2011-02-02    >  Group 4
(1,1) 2011-02-03 __/

扩展方法:

static IEnumerable<IEnumerable<T>> GroupAdjacent<T>(
this IEnumerable<T> source, Func<IEnumerable<T>, T, bool> adjacent)
{
var g = new List<T>();
foreach (var x in source)
{
if (g.Count != 0 && !adjacent(g, x))
{
yield return g;
g = new List<T>();
}
g.Add(x);
}
yield return g;
}

关于c# - 如何使用 "Linq to Objects"将一组连续的日期放在一个组中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8364911/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com