从C#列表对象计数具有相同模式的元素

时间:2019-02-20 17:49:56

标签: c# list linq count

嗨,我有一个C#列表对象,其中包含来自sql表的员工数据。现在有一个列名BadgeNumber,它具有6个字符或13个字符串值。我需要所有6个字符和13个字符徽章的计数。

我使用foreach循环来获取计数,并且工作正常。但是我想知道是否有更快的解决方案?

下面是我当前的实现方式。

var empDetails = GetAllEmployeeDetails();

int internalEmpCount;
int contractEmpCount;

foreach (var emp in empDetails)
{
    if (emp.BadgeNumber.Length == 6)
        internalEmpCount++;
    else if (emp.BadgeNumber.Length == 13)
        contractEmpCount++;
}
Console.WriteLine("{0}, {1}", internalEmpCount, contractEmpCount);

我查看了此解决方案here,但这更多的是关于重复值,因此,我认为我不能在此处使用group by,因为在我的情况下,所有徽章编号都是唯一的,而唯一的相似之处是徽章编号。但是任何建议或评论都值得赞赏!

3 个答案:

答案 0 :(得分:1)

不,没关系。 但是,您不需要进行13个长度限制检查。仅当您具有输入验证时。您可以将其更改为else,从而略微加快执行速度。

答案 1 :(得分:1)

您还可以按徽章编号 length 分组。如果将结果保存到字典中,则可以轻松获取所需的值。

var empDetails = GetAllEmployeeDetails();
var result = empDetails.GroupBy(x => x.BadgeNumber.Length)
                       .ToDictionary(k => k.Key, v => v.Count());
Console.WriteLine("{0}, {1}", result[6], result[13]);

请注意,与解决方案相比,这 not 更快, not 更高效, not 可读性更强!

答案 2 :(得分:0)

您的代码会一次枚举您的序列。要计算请求的值,需要枚举完整的序列。因此,您和LINQ都无法使其更高效。

唯一的效率是用一个switch语句替换两个if语句。这样,属性长度将仅计算一次:

switch (emp.BadgeNumber.Length)
{
    case 6:
        internalEmpCount++;
        break;
    case 13:)
        contractEmpCount++;
        break;
    // default: do nothing
}

或者,如果您完全确定长度为6或13:

if (emp.BadgeNumber.Length == 6)
    internalEmpCount++;
else
    contractEmpCount++;

更高的效率:让您的数据库进行计数

数据库查询的最慢部分之一是将所选数据从DBMS传输到本地进程。因此,限制传输的数据量是明智的。

如果列表的唯一原因是对元素进行计数,请考虑让数据库进行计数,并仅传输最终结果而不是完整列表。

IQueryable<EmpDetail> empDetails = ...

var result = empDetails
    // keep only the empDetail that you want to count:
    .Where(empDetail => empDetail.BadgeNumber.Length == 6
                     || empDetail.BadgeNumber.Length == 13)

    // make groups with same BadgeNumber.Length:
    .GroupBy(empDetail => empDetail.BadgeNumber.Length,

         // ResultSelector:
         (length, empDetailsWithThisLength) => new
         {
             Length = length,
             Count = empDetailsWithThisLength.Count,
         });

结果:两个项目的集合,每个项目都有[Length,Count]。因此只能传输4个整数。