2016-10-10 6 views
-1

Est-il possible de remplacer le Key par lequel un IGrouping est groupé?Remplacer la clé d'une IGrouping?

Je GROUPEMENT actuellement par un type anonyme comme celui-ci:

var groups = orders.GroupBy(o => new { o.Date.Year, o.Date.Month }); 

Mais maintenant ma clé de regroupement est un type anonyme. Je voudrais remplacer cette clé de regroupement par un Type défini, "YearMonth", avec une méthode ToString remplacée.

public class YearMonth 
{ 
    public int Year { get; set; } 
    public int Month { get; set; } 

    public override string ToString() 
    { 
     return Year + "-" + Month; 
    } 
} 

Y a-t-il un moyen de remplacer la clé de regroupement? Ou pour créer une nouvelle IGrouper de l'IGrouping existant avec une nouvelle clé de regroupement?

+4

Pourquoi voulez-vous un groupe sur un type, puis modifier la clé au lieu de juste en groupant sur la clé que vous * voulez * avoir? – Servy

+4

Il suffit d'utiliser 'o => new YearMonth (o.Date.Year, o.Date.Month)' à la place ... tant que 'YearMonth' remplace 'Equals' et' GetHashCode' de manière appropriée, cela devrait être bien ... au moins pour LINQ to Objects. –

+2

Il est 'readonly' pour une bonne raison, vous ne devriez pas modifier plus tard ce qui a été utilisé pour identifier des objets égaux. –

Répondre

1

Eh bien, personnellement, je voudrais simplement regrouper sur la valeur de la chaîne, car cela semble être ce que vous vous souciez vraiment de la clé.

Une autre option simple serait de créer une date représentant le mois en utilisant un jour constante:

orders.GroupBy(o => new DateTime (o.Date.Year, o.Date.Month, 1)) 

Ensuite, vous avez intégré l'égalité de valeur et la mise en forme de chaîne.

Vous pouvez faire YearMoth un immuable struct, qui vous donnera également la sémantique valeur d'égalité:

public struct YearMonth 
{ 
    public readonly int Year; 
    public readonly int Month; 

    public YearMonth(int year, int month) 
    { 
     Year = year; 
     Month = month; 
    } 

    public override string ToString() 
    { 
     return Year + "-" + Month; 
    } 
} 
+0

Cela semble plutôt bien! Pourquoi voudriez-vous grouper par la valeur de chaîne à la place? De cette façon, vous gardez toutes les données intactes, fortement typées et tout. –

+0

Vous souciez-vous de quelque chose d'autre que la valeur de la chaîne? Avez-vous besoin du mois et de l'année séparément? Les chaînes sont une clé de regroupement tout aussi valide que n'importe quel autre type, à condition que vous n'ayez pas à vous soucier de la sensibilité à la casse, des espaces, etc. Puisque vous contrôlez le format de chaîne, cela ne pose aucun problème. Comme je l'ai dit, c'est ce que je ferais jusqu'à ce que j'aie une raison impérieuse de faire quelque chose de différent. –

+0

Je pense que la chaîne est tout ce dont j'ai besoin _right now_, mais quelque part sur la ligne ayant les données séparées pourrait être utile. Je ne veux pas brûler des ponts juste pour le plaisir de "Je n'en ai pas besoin maintenant". –