当您有两个不同的分组时,如何使用groupBy

本文关键字:groupBy 何使用 两个 | 更新日期: 2023-09-27 18:21:03

我有这个样本数据

1/14/2012,5,Gas
1/15/2012,5,Gas
1/16/2012,5,Gas
1/17/2012,5,Gas
1/18/2012,5,Gas
1/19/2012,5,Gas
1/20/2012,5,Gas
1/21/2012,5,Gas
1/22/2012,5,Gas
1/23/2012,5,Gas
1/24/2012,5,Gas
1/25/2012,5,Gas
1/26/2012,5,Gas
1/27/2012,5,Gas
1/28/2012,5,Gas
1/29/2012,5,Gas
1/30/2012,5,Gas
1/31/2012,5,Gas
02/01/2012,5,Gas

有时我想按"月"answers"年"分组,有时我只想按"年"分组

  IEnumerable<IGrouping<TransactionsGroupedByMonthYear, TransactionDto>> groupTransactions = null;
DollarCapPeriod dollarCapPeriod = (DollarCapPeriod)Enum.Parse(typeof(DollarCapPeriod), reward.DollarCapPeriod);
switch (dollarCapPeriod)
{
    case DollarCapPeriod.Monthly:
  groupTransactions = filterdTransactions.GroupBy(x => new TransactionsGroupedByMonthYear { Month = x.TransactionDate.Month, Year = x.TransactionDate.Year });
        break;
    case DollarCapPeriod.Yearly:
  groupTransactions = filterdTransactions.GroupBy(x => new TransactionsGroupedByMonthYear { Month = 0, Year = x.TransactionDate.Year });
        break;
    default:
        break;
}

public class TransactionsGroupedByMonthYear
    {
        public int Month { get; set; }
        public int Year { get; set; }
    }

到目前为止,以上代码就是我所拥有的。第一个月有效。这是失败的一年。我试着用混凝土玻璃来分组,但不起作用。我被告知将Month设置为零,基本上让它忽略Month,并将其分组,就好像它只使用年份一样,但这不起作用。

当它将它们分组时,它只将它们分为19组(基本上每个记录一组)。当我查看调试器时,我看到的数据如下

   foreach (var group in groupTransactions)
            {
                var key = group.Key;
                int Month = key.Month;
                int Year = key.Year;
                System.Diagnostics.Debug.WriteLine("Month: {0}, Year: {1}", Month, Year);
            }

结果

Month: 0, Year: 2012
Month: 0, Year: 2012
Month: 0, Year: 2012
Month: 0, Year: 2012
Month: 0, Year: 2012
Month: 0, Year: 2012
Month: 0, Year: 2012
Month: 0, Year: 2012
Month: 0, Year: 2012
Month: 0, Year: 2012
Month: 0, Year: 2012
Month: 0, Year: 2012
Month: 0, Year: 2012
Month: 0, Year: 2012
Month: 0, Year: 2012
Month: 0, Year: 2012
Month: 0, Year: 2012
Month: 0, Year: 2012
Month: 0, Year: 2012
Month: 0, Year: 2012
Month: 0, Year: 2012
Month: 0, Year: 2012
Month: 0, Year: 2012
Month: 0, Year: 2012
Month: 0, Year: 2012
Month: 0, Year: 2012
Month: 0, Year: 2012

当它应该只有一条记录,并且所有记录都分组时。因为它们都来自2012

编辑

斯科特·里皮-我试过你给的,但我还是没用。

 groupTransactions = filterdTransactions.GroupBy(
                            // Key selector:
                            x => x.TransactionDate.Year,
                            // result selector:
                            (year, items) => new TransactionsGroupedByMonthYear{ Year = year, Month = 0, Transactions = items});

public class TransactionsGroupedByMonthYear
{
    public int Month { get; set; }
    public int Year { get; set; }
    public IList<TransactionDto> Transactions { get; set; }
}
Error   1   Cannot convert lambda expression to type 'System.Collections.Generic.IEqualityComparer<int>' because it is not a delegate type      

编辑2

我刚刚注意到你有项目.toList()

现在我得到这个

Error   1   Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<CCRecomendator.Framework.Domain.DTO.TransactionsGroupedByMonthYear>' 
                                        to 'System.Collections.Generic.IEnumerable<System.Linq.IGrouping<CCRecomendator.Framework.Domain.DTO.TransactionsGroupedByMonthYear,CCRecomendator.Framework.Domain.DTO.TransactionDto>>'. An explicit conversion exists (are you missing a cast?)

所以我看到的问题是,这返回了一个不同的类型。我需要使用"Month"answers"Yearly"开关分组代码来返回相同的数据类型(否则我只会使用匿名类型)。

当您有两个不同的分组时,如何使用groupBy

为什么GroupBy不工作

TransactionsGroupedByMonthYear不会覆盖相等运算符,因此GroupBy将使用引用比较——换句话说,在比较时没有两个TransactionsGroupedByMonthYear相等。

最简单的解决方案是按照你在第一个例子中所做的。。。请改用匿名对象。匿名对象会自动覆盖相等运算符,它们非常适合GroupBy操作。

否则,您将不得不重写TransactionsGroupedByMonthYear类中的.Equals.GetHashCode方法。

为什么要使用GroupBy

您是否确实需要每年分组项目的列表?如果你只想得到一个不同的年份列表,你不应该使用GroupBy,你应该使用Distinct

根据TransactionsGroupedByMonthYear的名称判断,我看到了MonthYear,但我猜你应该也有Transactions属性。如果这是真的,那就继续读下去。

您的代码似乎正在尝试输出存储在TransactionsGroupedByMonthYear中的分组项目列表
为此,您应该使用以下重载:GroupBy(keySelector, resultSelector)

基本上,这个重载允许您对每个匹配的组执行一些操作,例如创建一个TransactionsGroupedByMonthYear:

groupTransactions = filterdTransactions.GroupBy(
    // Key selector:
    x => new { x.Year },
    // result selector:
    (key, items) => new TransactionsGroupedByMonthYear{ Year = key.Year, Month = 0, Transactions = items.ToList()})
);

回复:编辑2

您在Edit 2中看到错误的原因是因为以下行:

IEnumerable<IGrouping<TransactionsGroupedByMonthYear, TransactionDto>> groupTransactions = null;

应该是:

IEnumerable<TransactionsGroupedByMonthYear> groupTransactions = null;

你只是声明了错误的类型。