简体   繁体   English

字典<K, List<TObject> &gt; 从对象集合

[英]Dictionary<K, List<TObject>> from collection of objects

I am interested is there a way to write to following code using lambda expression or LINQ:我感兴趣的是有没有一种方法可以使用 lambda 表达式或 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;

Dictionary>> result = new Dictionary>>();字典>>结果=新字典>>(); List> subCategories = null;列表> subCategories = null; IdKeyPair subCategorie = null; IdKeyPair subCategorie = 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);
                }
            }

I tried many ways and fails allays.我尝试了很多方法,但都失败了。 This was one of my attempts:这是我的尝试之一:

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

Result:结果:

*{
  "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"
    }
  ]*

** Expected: "zemljiste" should be:** ** 预期:“zemljiste”应该是:**

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

You can Group by MainCategoryKey and use ToDictionary to convert the grouped result to dictionary.您可以按MainCategoryKey并使用ToDictionary将分组结果转换为字典。 and convert the values to new IdKeyPair<ulong>((ulong)z.SubCategory, z.SubCategoryKey)并将值转换为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());

Update as per comment根据评论更新

To select distinct values, apply Distinct function after Select the columns SubCategory and SubCategoryKey , like:要选择不同的值,请在SelectSubCategorySubCategoryKey之后应用Distinct函数,例如:

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

I hope this will help you out.我希望这会帮助你。

Inspired by @Sajid first answer I come up with solution using moreLINQ:受@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());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM