#c# #linq #group-by
Вопрос:
У меня есть простой список, который я хотел бы отобразить, сгруппированный по тому, к какой категории он относится. Во всех примерах, которые я видел, используется GroupBy, но с одним идентификатором, мне трудно понять, как это сделать со списком. Это нормально, если продукт отображается в обеих категориях.
public class Product
{
public int Id { get; set; }
public string Title { get; set; }
public List<Category> Categories { get; set; }
}
StringBuilder ProductList = new StringBuilder();
var p = _products.GroupBy(a => a.Categories);
foreach (var item in p)
{
ProductList.Append($"<p><strong>{item.Key}</strong><br/>");
foreach (var e in item)
{
ProductList.Append($"{e.Title}");
ProductList.Append("</p>");
}
}
Комментарии:
1. Вы хотите показать значения для каждой категории или для определенного набора категорий?
Ответ №1:
Вот решение с образцами данных, которые вы можете проверить самостоятельно:
var categories = Enumerable.Range(0, 10).Select(n => new Category { Id = n }).ToArray();
var products = new[]
{
new Product { Id = 1, Title = "P1", Categories = new List<Category> { categories[0], categories[1], categories[2] } },
new Product { Id = 2, Title = "P2", Categories = new List<Category> { categories[0], categories[1], categories[3] } },
new Product { Id = 3, Title = "P3", Categories = new List<Category> { categories[0], categories[2], categories[3] } },
new Product { Id = 4, Title = "P4", Categories = new List<Category> { categories[0], categories[2], categories[3] } },
new Product { Id = 5, Title = "P5", Categories = new List<Category> { categories[0], categories[3], categories[5] } },
new Product { Id = 6, Title = "P6", Categories = new List<Category> { categories[0], categories[4], categories[5] } },
};
var categoryGroups =
from p in products
from c in p.Categories
group p by c.Id into g
select g;
foreach (var categoryGroup in categoryGroups)
{
Console.WriteLine($"Category {categoryGroup.Key}:");
foreach (var product in categoryGroup)
{
Console.WriteLine($"tProduct {product.Id}: {product.Title}");
}
Console.WriteLine("-----------------------------------------------------");
}
Я предполагаю, что класс Category
имеет некоторое свойство идентификатора , например Id
, для группировки по. Если это группировка на основе ссылок, которую вы можете group p by c.Id into g
заменить group p by c into g
.
Ответ №2:
Вы можете использовать SelectMany
для сглаживания списка в кортежи (Product, Category)
, а затем использовать GroupBy
для группировки товаров по категориям.
StringBuilder ProductList = new StringBuilder();
var p = _products
.SelectMany(a => a.Categories, (prod, cat) => (prod, cat))
.GroupBy(tuple => tuple.cat, tuple => tuple.prod);
foreach (var item in p)
{
ProductList.Append($"<p><strong>{item.Key}</strong><br/>");
foreach (var e in item)
{
ProductList.Append(e.Title);
ProductList.Append("</p>");
}
}