Comment puis-je utiliser c # et Linq pour obtenir un result
de la liste suivante:
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}
Je sais que je devrais utiliser GroupBy
ou Distinct
, mais je comprends comment obtenir ce dont j'ai besoin
List<Product> result = pr.GroupBy(g => g.Title, g.Price).ToList(); //not working
List<Product> result = pr.Distinct(...);
Veuillez aider
Il regroupe les propriétés requises et sélectionne:
List<Product> result = pr.GroupBy(g => new { g.Title, g.Price })
.Select(g => g.First())
.ToList();
Bien qu'un nouveau type anonyme fonctionne, il pourrait être plus logique, plus lisible et consommable en dehors de votre méthode de créer votre propre type ou d'utiliser un Tuple . (D'autres fois, il peut simplement suffire d'utiliser une chaîne délimitée: 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 ce qui concerne l'obtention du jeu de résultats souhaité, la réponse fournie suggère simplement de renvoyer le premier, et peut-être que cela convient à vos besoins, mais idéalement, vous devez fournir un moyen par lequel Color
est agrégé ou ignoré.
Par exemple, vous préférez peut-être lister les couleurs incluses, d'une manière ou d'une autre:
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();
Dans le cas d'une propriété de chaîne simple pour la couleur, il peut être judicieux de simplement les concaténer. Si vous aviez une autre entité là-bas, ou si vous ne voulez tout simplement pas retirer ces informations, il serait peut-être préférable d'avoir une autre entité qui possède une collection de ce type d'entité. Par exemple, si vous regroupiez par titre et couleur, vous souhaiterez peut-être afficher le prix moyen ou une fourchette de prix, où le simple fait de sélectionner le premier de chaque groupe vous en empêcherait.
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();