我遇到一个问题,即给定的项目可能有多个密钥,我需要在组中出现在两个集合中。这可能吗?
这些项目看起来像这样
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}
这有可能吗?
答案 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
将创建一个字典,其中键是每个组的键(类别名称),值是与类别名称关联的项目列表。