Подсчет элементов с одинаковым шаблоном из объекта списка C # - PullRequest
0 голосов
/ 20 февраля 2019

Привет! У меня есть объект списка 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);

Я смотрел на это решение здесь , но это большенасчет дублирующихся значений, и, таким образом, я не думаю, что смогу использовать здесь группу, так как в моем случае все номера значков уникальны, и только сходство - это длина номеров значков.Но любые предложения или комментарии приветствуются!

Ответы [ 3 ]

0 голосов
/ 20 февраля 2019

Вы также можете группировать по номеру badgenumber длина .Если вы передадите результат в словарь, вы можете легко получить нужные значения.

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]);

Обратите внимание, что это не быстрее, не более эффективно, и не более читабельно, чем ваше решение!

0 голосов
/ 21 февраля 2019

Ваш код перечисляет вашу последовательность ровно один раз.Чтобы рассчитать запрошенные значения, необходимо перечислить полную последовательность.Следовательно, ни вы, ни LINQ не можете сделать это более эффективным.

Единственная эффективность, которую вы можете получить, - это заменить два оператора if одним оператором switch.Таким образом, длина свойства будет оцениваться только один раз:

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++;

Больше эффективности: пусть ваша база данныхвыполнить подсчет

Одна из более медленных частей запроса к базе данных - это передача выбранных данных из СУБД в локальный процесс.Следовательно, разумно ограничить количество транспортируемых данных.

Если единственной причиной для вашего списка является подсчет элементов, рассмотрите возможность позволить вашей базе данных выполнять подсчет и переносить только конечный результатвместо полного списка.

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,
         });

Результат: набор из двух элементов, каждый из которых имеет [Длина, Количество].Таким образом, будет транспортировано только 4 целых числа.

0 голосов
/ 20 февраля 2019

Нет, все в порядке. Однако вам не требуется проверка ограничения длины 13.Это только если у вас есть подтверждение ввода.Вы можете изменить его на другое, ускоряющее исполнение незначительно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...