Как извлекать уникальные объекты с помощью Linq

#c# #asp.net #json #linq #asp.net-core

#c# #asp.net #json #linq #asp.net-ядро

Вопрос:

Привет, может кто-нибудь помочь, пожалуйста, у меня есть список, содержащий мои промо-коды, и в списке я хотел бы возвращать только промо-коды, которые появляются один раз, т.Е. Не имеют дубликатов, см. Ниже Данные из JSON, я хотел бы вернуть промо-коды A123 и B500 и сохранить их в другом списке.

 [
   {
    "PromCode": "A123",
    "Priority": 1,
    "offer": "Win a Free Cap",
    "StartDte": "2020-08-11T00:16:23.184Z",
    "endDte": "2020-09-10T17:16:23.184Z",
  }, 
  {
    "PromCode": "A100",
    "Priority": 1,
    "offer": "Win a perfume",
    "StartDte": "2020-08-11T00:16:23.184Z",
    "endDte": "2020-09-10T17:16:23.184Z",
  },
{
    "PromCode": "A100",
    "Priority": 2,
    "offer": "Win a Phone pouch",
    "StartDte": "2020-09-11T00:16:23.184Z",
    "endDte": "2020-10-10T17:16:23.184Z",
  },
 {
    "PromCode": "B500",
    "Priority": 1,
    "offer": "Win a free router",
    "StartDte": "2020-08-11T00:16:23.184Z",
    "endDte": "2020-09-10T17:16:23.184Z",
  },
 {
    "PromCode": "H300",
    "Priority": 2,
    "offer": "Win a free router",
    "StartDte": "2020-08-11T00:16:23.184Z",
    "endDte": "2020-09-10T17:16:23.184Z",
  },

]
 

У меня есть список, содержащий все эти рекламные коды, как показано ниже, примечание: и я уже
успешно сериализовал объекты JSON

 var existingProms = await _Repo.GetAllPromCodes(promCodeList);
 

я попытался получить те, которые появляются один раз в списке следующим образом

   var distinctList = existingProms.GroupBy(x => x.PromCode).Where(y => y.Count() == 1)
                   .Select(x => x.Key.ToString()).ToList();
 

Пожалуйста, обратите внимание, что приведенное выше возвращает отдельные prom (B500, A123, H300), но возвращает только PromCode, а не все остальные поля в этом объекте.Я хочу вернуть список всех моих объектов, где они разные, а где нет, и где приоритет равен = 1. это означает, что конечный результат distinct List должен содержать два объекта в результате, см. Иллюстрацию ниже.

 distinctList = {
    "PromCode": "A123",
    "Priority": 1,
    "offer": "Win a Free Cap",
    "StartDte": "2020-08-11T00:16:23.184Z",
    "endDte": "2020-09-10T17:16:23.184Z",
  }, 
 {
    "PromCode": "B500",
    "Priority": 1,
    "offer": "Win a free coffee mug",
    "StartDte": "2020-08-11T00:16:23.184Z",
    "endDte": "2020-09-10T17:16:23.184Z",
  },

 

Комментарии:

1. Вы ищете уникальные , а не отдельные объекты. Distinct означает возврат только одной строки, даже если есть дубликаты. У LINQ есть Distinct() метод, но это не то, чего вы действительно хотите

Ответ №1:

Просто дополнительная модификация вашего исходного запроса приведет вас туда:

         var distinctList = existingProms
            .GroupBy(x => x.PromCode)
            .Where(y => y.Count() == 1 amp;amp; y.First().Priority == 1)
            .Select(x => x.First())
            .ToList();
 

Поскольку y.Count() == 1 гарантирует, что вы получите только один элемент в группе, который вы можете использовать First , чтобы взять его и отфильтровать Priority по нему, .Where(y => y.Count() == 1 amp;amp; y.First().Priority == 1) а при следующем вызове метода выбрать этот объект.

Выше был приведен пример синтаксиса метода, в синтаксисе запроса это будет:

     var distinctList = (from ep in existingProms
                        group ep by ep.PromCode into g
                        where g.Count() == 1 amp;amp; g.First().Priority == 1
                        select g.First())
                        .ToList();
 

Ответ №2:

В вашей groupby вам нужно выбрать первый элемент группировки вместо выбора Key :

 var distinctList = existingProms
    .GroupBy(x => x.PromCode)
    .Where(y => y.Count() == 1)
    .Select(x => x.First()) // Changed from .Select(x => x.Key.ToString())
    .ToList();