толковый словарь из коллекции предметов - PullRequest
0 голосов
/ 12 марта 2020

Меня интересует, есть ли способ написать следующий код, используя лямбда-выражение или LINQ:

public class IdKeyPair<T>
    {
        public T Id { get; set; }
        public string Key { get; set; }

        public IdKeyPair()
        {
        }

        public IdKeyPair(T id, string key)
        {
            Id = id;
            Key = key;
        }

public class AdvertisementObjectEntityExtended
    {
    public List<string> Images { get; set; } = new List<string>();

    public ulong Id { get; set; }

    [Keyword]
    public string Uniq { get; set; }

    [Keyword]
    public string UserUniq { get; set; }

    public bool IsRentable { get; set; }
    public bool Active { get; set; } = false;
    public int MainCategory { get; set; }
    public int SubCategory { get; set; }
    public DateTime CreatedAt { get; set; }
    public DateTime LastEdited { get; set; }
    public string Title { get; set; }
    public ulong Price { get; set; }
    public double Quadrature { get; set; }
    public bool Parking { get; set; }
    public bool Garage { get; set; }
    public bool WiFi { get; set; }
    public bool Elevator { get; set; }
    public bool FurnishState { get; set; }
    public AdvertisementObjectOrientation Orientation { get; set; }
    public AdvertisementObjectStructure Structure { get; set; }
    public bool Deposit { get; set; }
    public bool Duplex { get; set; }
    public int Badrooms { get; set; }
    public int Bathrooms { get; set; }
    public int Toilets { get; set; }
    public int Pantries { get; set; }
    public bool SeparateKitchen { get; set; }
    public bool LaundryAndDryingRoom { get; set; }
    public int CommonAreas { get; set; }
    public bool Basement { get; set; }
    public int FloorsOfTheBuilding { get; set; }
    public bool Terrace { get; set; }
    public bool Balcony { get; set; }
    public bool Loggia { get; set; }
    public bool FrenchBalcony { get; set; }
    public string Address { get; set; }
    public string AdditionalDescription { get; set; }
    public AdvertisementObjectHeating HeatingType { get; set; }
    public AdvertisementObjectDescription ObjectDescription { get; set; }
    public int ConstructionYear { get; set; }
    public AdvertisementObjectPropertyCondition PropertyCondition { get; set; }
    public bool EnergyPassport { get; set; }
    public bool ImmediatelyHabitable { get; set; }
    public bool VATRefount { get; set; }
    public bool ExchangePossible { get; set; }
    public bool Filed { get; set; }
    public bool Mortgaged { get; set; }
    public bool Longue { get; set; }
    public bool Wardrobe { get; set; }
    public bool Penthouse { get; set; }
    public bool WarmWater { get; set; }
    public bool Intercom { get; set; }
    public bool Climate { get; set; }
    public bool Phone { get; set; }
    public bool Alarm { get; set; }
    public bool Security { get; set; }
    public bool SecurityDoor { get; set; }
    public bool VideosSurveillance { get; set; }
    public bool CableTV { get; set; }
    public bool Fireplace { get; set; }
    public string VideoURL { get; set; }
    public int ApartmentLevel { get; set; }
    public AdvertisementObjectBelongingSurfaces BelongingSurfaces { get; set; }
    public string Description { get; set; }

    #region Location
    public ulong CityID { get; set; }
    public ulong CityLocationID { get; set; }
    public string Location { get; set; }
    #endregion

    #region GeoLocation
    public double Longitude { get; set; }
    public double Latitude { get; set; }
    public int Zoom { get; set; }
    public string Showcase3D { get; set; }
    #endregion

    public string MainCategoryKey{ get; set; }
    public string SubCategoryKey { get; set; }
}

List<AdvertisementObjectEntityExtended> advertisements = await _elasticSearchService.GetAllForLoggedInUserAsync(identity);

Dictionary<string, List<IdKeyPair<ulong>>> result = 
    new Dictionary<string, List<IdKeyPair<ulong>>>();

List<IdKeyPair<ulong>> subCategories = null;
IdKeyPair<ulong> subCategorie = null;

Словарь >> result = new Dictionary >> (); Список> подкатегории = ноль; IdKeyPair подкатегория ie = null;

            foreach (AdvertisementObjectEntityExtended advertisement in advertisements)
            {
                string key = advertisement.MainCategoryKey.ToUpper();

                if (result.ContainsKey(advertisement.MainCategoryKey))
                {
                    subCategorie = new IdKeyPair<ulong>((ulong)advertisement.SubCategory, advertisement.SubCategoryKey);

                    subCategories = result[key];

                    if (!subCategories.Any(x => x.Id == subCategorie.Id && x.Key == subCategorie.Key))
                    {
                        result[key].Add(subCategorie);
                    }
                }
                else
                {
                    subCategorie = new IdKeyPair<ulong>((ulong)advertisement.SubCategory, advertisement.SubCategoryKey);

                    subCategories = new List<IdKeyPair<ulong>>()
                    {
                        subCategorie
                    };

                    result.Add(key, subCategories);
                }
            }

Я перепробовал много способов и потерпел неудачу. Это была одна из моих попыток:

IEnumerable<IGrouping<string, IdKeyPair<ulong>>> result = 
    advertisements.GroupBy(x => x.MainCategoryKey, (key, group) =>  ????);

Результат:

*{
  "stambenI_PPROSTOR": [
    {
      "id": 11,
      "key": "KUCA"
    }
  ],
  "vikendica": [
    {
      "id": 38,
      "key": "JEZERSKA"
    }
  ],
  "poslovnI_PROSTOR": [
    {
      "id": 8,
      "key": "KIOSK"
    }
  ],
  "ugostiteljskI_OBJEKAT": [
    {
      "id": 15,
      "key": "KAFIC"
    },
    {
      "id": 20,
      "key": "SPLAV"
    },
    {
      "id": 35,
      "key": "KUHINJA"
    }
  ],
  "zemljiste": [
    {
      "id": 41,
      "key": "GRADJEVINSKO"
    },
    {
      "id": 42,
      "key": "INDUSTRIJSKO"
    },
    {
      "id": 42,
      "key": "INDUSTRIJSKO"
    },
    {
      "id": 42,
      "key": "INDUSTRIJSKO"
    }
  ]*

** Ожидается: "zemljiste" должно быть: **

*"zemljiste": [
    {
      "id": 41,
      "key": "GRADJEVINSKO"
    },
    {
      "id": 42,
      "key": "INDUSTRIJSKO"
    }
  ]*

Ответы [ 2 ]

1 голос
/ 13 марта 2020

Вдохновленный первым ответом @Sajid, я придумаю решение, используя moreLINQ:

Dictionary<string, List<IdKeyPair<ulong>>> result = advertisements
    .GroupBy(x => x.MainCategoryKey)
    .ToDictionary(
        x => x.Key,
        y => y.DistinctBy(d => d.SubCategoryKey)
            .Select(z => new IdKeyPair<ulong>((ulong)z.SubCategory, z.SubCategoryKey))
            .ToList());
1 голос
/ 12 марта 2020

Вы можете группировать по MainCategoryKey и использовать ToDictionary , чтобы преобразовать сгруппированный результат в словарь. и преобразовать значения в new IdKeyPair<ulong>((ulong)z.SubCategory, z.SubCategoryKey)

Dictionary<string, List<IdKeyPair<ulong>>> result = advertisements
    .GroupBy(x => x.MainCategoryKey)
    .ToDictionary(
     x => x.Key, 
     y => y.Select(z => new IdKeyPair<ulong>((ulong)z.SubCategory, z.SubCategoryKey)).ToList());

Обновить согласно комментарию

Чтобы выбрать отдельные значения, примените функцию Distinct после Select столбцы SubCategory и SubCategoryKey, например:

Dictionary<string, List<IdKeyPair<ulong>>> result1 = advertisements
    .GroupBy(x => x.MainCategoryKey)
    .ToDictionary(x => x.Key, y => y.Select(a => new {a.SubCategory, a.SubCategoryKey })
        .Distinct()
        .Select(z => new IdKeyPair<ulong>((ulong)z.SubCategory, z.SubCategoryKey)).ToList());

Надеюсь, это поможет вам.

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