Linq列表中的记录数

时间:2014-01-05 22:06:05

标签: c# linq count

尝试使用expresisons和谓词按两种类型对列表进行分组并计算。 我有两个列表:yearList和supList。它们都包含名为FIPS和YEAR的列,我需要做的就是在一个列表中循环遍历所有可能的FIPS和Years(yearList)。然后我需要找到FIPS和Year在第二个列表(supList)中出现的次数,并将该值写入yearlLst。 下面你会看到一个数据样本的样本,例如当FIPS = 1001和Year = 2001表格传递时,我应该从我的supList返回一个计数1并将该值写入我的yearList中的y.countEnviofnd当返回FIPS = 1001并且在count = 2中传递Year = 2002时。我试过多次尝试这样做,但似乎无法得到它。

这是我需要比较的样本列表,并从中查找计数:这将是我在下面的代码示例中的supList。

FIPS    YEAR
------------
1001    2001
1001    2002
1003    2006
1002    2001
1001    2002
1003    2005
1003    2006

这将是所有可能的FIPS和我可能拥有的年份:从1001开始为fips和增加,但每个fips都有一年的记录从2001年开始并上升到2004年。还有更多,但这里是一个样品。在下面的代码中,这将是yearList

FIPS    DATE
------------
1001    2001
1001    2002
1001    2003
1001    2004
1002    2001
1002    2002
1002    2003
1002    2004
1003    2001
1003    2002
1003    2003
1003    2004

我已经尝试了所有这些LINQ表达式,似乎没有做到这一点。它可以为所有东西返回0或1。

foreach(Year y in yearList)
{
    int countY = supList.Where(p => p.FIPS == Convert.ToString(y.FIPS) && p.year==y.year).Count();
    int countY = supList.GroupBy(p => p.FIPS == Convert.ToString(y.FIPS) && p.year==y.year).Count();
    int countY  = supList.FindAll(i => i.FIPS == Convert.ToString(y.FIPS) && i.year == y.year).Count(); 

    y.countenviofnd = countY;
}   

1 个答案:

答案 0 :(得分:2)

使用Where()Count()将起作用,这是我在LINQPad 4中制作的示例:

void Main()
{
    var supList = new List<Data>() {
        new Data { FIPS = 1001, Year = 2001 },
        new Data { FIPS = 1001, Year = 2002 },
        new Data { FIPS = 1003, Year = 2006 },
        new Data { FIPS = 1002, Year = 2001 },
        new Data { FIPS = 1001, Year = 2002 },
        new Data { FIPS = 1003, Year = 2005 },
        new Data { FIPS = 1003, Year = 2006 }
    };

    var yearList = new List<Data>() {
        new Data { FIPS = 1001, Year = 2001 },
        new Data { FIPS = 1001, Year = 2002 },
        new Data { FIPS = 1001, Year = 2003 },
        new Data { FIPS = 1001, Year = 2004 },
        new Data { FIPS = 1002, Year = 2001 },
        new Data { FIPS = 1002, Year = 2002 },
        new Data { FIPS = 1002, Year = 2003 },
        new Data { FIPS = 1002, Year = 2004 },
        new Data { FIPS = 1003, Year = 2001 },
        new Data { FIPS = 1003, Year = 2002 },
        new Data { FIPS = 1003, Year = 2003 },
        new Data { FIPS = 1003, Year = 2004 },
    };

    foreach (var year in yearList)
    {
        supList
            .Where(p => p.FIPS == year.FIPS && p.Year == year.Year)
            .Count()
            .Dump(string.Format("Using Where().Count() for [FIPS:{0}, Year:{1}]", year.FIPS, year.Year));
    }
}

// Define other methods and classes here
class Data
{
    public int FIPS { get; set; }
    public int Year { get; set; }
}

我得到了以下输出:

Using Where().Count() for [FIPS:1001, Year:2001] 
1 

Using Where().Count() for [FIPS:1001, Year:2002] 
2 

Using Where().Count() for [FIPS:1001, Year:2003] 
0 

Using Where().Count() for [FIPS:1001, Year:2004] 
0 

Using Where().Count() for [FIPS:1002, Year:2001] 
1 

Using Where().Count() for [FIPS:1002, Year:2002] 
0 

Using Where().Count() for [FIPS:1002, Year:2003] 
0 

Using Where().Count() for [FIPS:1002, Year:2004] 
0 

Using Where().Count() for [FIPS:1003, Year:2001] 
0 

Using Where().Count() for [FIPS:1003, Year:2002] 
0 

Using Where().Count() for [FIPS:1003, Year:2003] 
0 

Using Where().Count() for [FIPS:1003, Year:2004] 
0 

请注意,我创建了int类型的数据,避免了任何可能出现的问题。我建议你在数据检索期间/之后进行一次转换。

另请注意,根据您提供的数据,只有一个FIPS / Year组合有超过1条记录(第二个输出)。

根据您的需要,您可以使用某种GroupBy表达式做得更好。

更新:为了提高性能,假设数据类型已经转换为兼容类型,您可以添加以下查询来同时对每个有效组合进行计数:

var query = from year in yearList
            join sup in supList 
                on new { year.FIPS, year.Year } equals new { sup.FIPS, sup.Year }
            group sup by new { sup.FIPS, sup.Year } into p
            select new { p.Key.FIPS, p.Key.Year, Count = p.Count() };
query.Dump("join/group query");

Dump()语句仅适用于LINQPad输出,您可以使用ToList()或其他内容。结果如下3行:

FIPS Year Count
==== ==== =====
1001 2001 1
1001 2002 2
1002 2001 1

请注意,由于我使用多个键进行分组(因此使用FIPS + Year的anon对象),因此它有点复杂。