当每个项目可以有多个密钥时,是否可以对集合进行分组?

时间:2014-12-18 15:53:55

标签: c# linq lambda

我遇到一个问题,即给定的项目可能有多个密钥,我需要在组中出现在两个集合中。这可能吗?

这些项目看起来像这样

class Item
{
   Category mainCat {get;set;}

   IEnumerable<Category> RelatedCategories {get;set;}

   String RefNumber {get;set;}
}

class Category
{
   String CatName {get;set;}
}

我需要按类别对项目集合进行分组,但如果项目具有相关类别,则还需要在相关类别的组中显示。

因此,作为一个最简单的例子,我将在集合中拥有以下项目实例:

参考:A1 类别:Cat_01 RelatedCategories:{Cat_02}

分组后我想要的输出是:

键:Cat_01,项目{A1} 键:Cat_02,项目{A1}

这有可能吗?

3 个答案:

答案 0 :(得分:1)

所以你有一个Item引用列表,你想要一个包含键(类别)和相关Item实例的字典。下面的代码就是这样。

var dict = new Dictionary<Category, List<Item>>();
foreach (var item in ItemsList)
{
    AddToCategory(item, item.mainCat);
    foreach (var cat in item.RelatedCategories)
    {
        AddToCategory(item, cat);
    }
}

void AddToCategory(Item item, Category cat)
{
    List<Item> categoryItems;
    if (!dict.TryGetValue(cat, out categoryItems))
    {
        categoryItems = new List<Item>();
        dict.Add(cat, categoryItems);
    }
    categoryItems.Add(item);
}

我没有看到使用简单的LINQ表达式做到这一点的方法,尽管很有可能有办法。

答案 1 :(得分:1)

可以使用LINQ查询:

var query = from item in source
            from category in item.RelatedCategories.Concat(new[] { item.MainCat })
            group item by category.CatName into g
            select g;

虽然这是使用LINQ的少数情况之一,但可能不是最易读的解决方案。

答案 2 :(得分:1)

是的,您可以通过以下方式进行。

var dictionary = item.RelatedCategories
     .Concat(Enumerable.Repeat(item.mainCat, 1))
     .ToDictionary(c => c.CatName, c => item);

这将获取相关类别并连接主要类别,并使用ToDictionary将每个类别名称与给定项目相关联。

如果你正在处理一个项目列表,它会变得更加复杂,因为我认为在这种情况下你需要一个Dictionary<string, List<Item>>

var dictionary = items.SelectMany(i => i.RelatedCategories
                                        .Concat(Enumerable.Repeat(i.mainCat, 1))
                                        .Select(c => new { c.CatName, Item = i}))
                      .GroupBy(a => a.CatName)
                      .ToDictionary(a => a.Key, a => a.ToList());

此处内部查询正在创建匿名类的枚举,这些类将每个类别名称与项目相关联。 SelectMany会将枚举变为一个。然后GroupBy将根据类别名称将这些匿名类分组。然后ToDictionary将创建一个字典,其中键是每个组的键(类别名称),值是与类别名称关联的项目列表。