c# - query - linq distintas o agrupadas por múltiples propiedades
linq notation c# (2)
¿Cómo puedo usar c # y Linq para obtener un result
de la siguiente lista:
var pr = new List<Product>()
{
new Product() {Title="Boots",Color="Red", Price=1},
new Product() {Title="Boots",Color="Green", Price=1},
new Product() {Title="Boots",Color="Black", Price=2},
new Product() {Title="Sword",Color="Gray", Price=2},
new Product() {Title="Sword",Color="Green",Price=2}
};
Result
:
{Title="Boots",Color="Red", Price=1},
{Title="Boots",Color="Black", Price=2},
{Title="Sword",Color="Gray", Price=2}
Sé que debo usar GroupBy
o Distinct
, pero entiendo cómo obtener lo que se necesita
List<Product> result = pr.GroupBy(g => g.Title, g.Price).ToList(); //not working
List<Product> result = pr.Distinct(...);
Por favor ayuda
Se agrupan por propiedades necesarias y se seleccionan:
List<Product> result = pr.GroupBy(g => new { g.Title, g.Price })
.Select(g => g.First())
.ToList();
Si bien un nuevo tipo anónimo funcionará, podría tener más sentido, ser más legible y consumible fuera de su método para crear su propio tipo o usar una Tuple . (Otras veces simplemente puede ser suficiente usar una cadena delimitada: string.Format({0}.{1}, g.Title, g.Price)
)
List<Product> result = pr.GroupBy(g => new Tuple<string, decimal>(g.Title, g.Price))
.ToList();
List<Product> result = pr.GroupBy(g => new ProductTitlePriceGroupKey(g.Title, g.Price))
.ToList();
En cuanto a obtener el conjunto de resultados que desea, la respuesta proporcionada sugiere devolver el primero, y quizás esté bien para sus propósitos, pero lo ideal sería que proporcionara un medio por el cual se agregue o ignore el Color
.
Por ejemplo, quizás prefieras enumerar los colores incluidos, de alguna manera:
List<Product> result = pr
.GroupBy(g => new Tuple<string, decimal>(g.Title, g.Price))
.Select(x => new Product()
{
Title = x.Key.Item1,
Price = x.Key.Item2,
Color = string.Join(", ", x.Value.Select(y => y.Color) // "Red, Green"
})
.ToList();
En el caso de una propiedad de cadena simple para el color, puede tener sentido simplemente concatenarlos. Si tenía otra entidad allí, o simplemente no quiere abstraer esa información, tal vez sería mejor tener otra entidad que tenga una colección de ese tipo de entidad. Por ejemplo, si estuviera agrupando por título y color, es posible que desee mostrar el precio promedio, o un rango de precios, donde simplemente seleccionando el primero de cada grupo le impediría hacerlo.
List<ProductGroup> result = pr
.GroupBy(g => new Tuple<string, decimal>(g.Title, g.Price))
.Select(x => new ProductGroup()
{
Title = x.Key.Item1,
Price = x.Key.Item2,
Colors = x.Value.Select(y => y.Color)
})
.ToList();