C’est assez simple, mais j’en suis perdu: avec ce type de jeu de données:
UserInfo(name, metric, day, other_metric)
et cet exemple de données:
joe 1 01/01/2011 5
jane 0 01/02/2011 9
john 2 01/03/2011 0
jim 3 01/04/2011 1
jean 1 01/05/2011 3
jill 2 01/06/2011 5
jeb 0 01/07/2011 3
jenn 0 01/08/2011 7
Je voudrais récupérer un tableau qui répertorie les mesures dans l'ordre (0,1,2,3 ..) avec le nombre total de fois où le comptage a lieu. Donc, dans cet ensemble, vous vous retrouveriez avec:
0 3
1 2
2 2
3 1
Je suis aux prises avec la syntaxe LINQ mais je suis coincé sur l'endroit où mettre un groupe et compter .... toute aide?
POST Edit: Je n'ai jamais réussi à obtenir les réponses affichées, car elles renvoyaient toujours un enregistrement avec le nombre de comptes différents. Cependant, j'ai pu créer un exemple LINQ to SQL qui a fonctionné:
var pl = from r in info
orderby r.metric
group r by r.metric into grp
select new { key = grp.Key, cnt = grp.Count()};
Ce résultat m'a donné un ensemble ordonné d'enregistrements avec des "métriques" et le nombre d'utilisateurs associés à chacun. Je suis clairement nouveau pour LINQ en général et pour mon œil inexpérimenté, cette approche semble très similaire à l'approche LINQ pure, mais m'a donné une réponse différente.
Après avoir appelé GroupBy
, vous obtenez une série de groupes IEnumerable<Grouping>
, où chaque groupe lui-même expose le Key
utilisé pour créer le groupe et constitue également un IEnumerable<T>
parmi les éléments présents. votre jeu de données d'origine. Vous devez simplement appeler Count()
sur ce groupe pour obtenir le sous-total.
foreach(var line in data.GroupBy(info => info.metric)
.Select(group => new {
Metric = group.Key,
Count = group.Count()
})
.OrderBy(x => x.Metric)
{
Console.WriteLine("{0} {1}", line.Metric, line.Count);
}
C'était une réponse brillamment rapide, mais j'ai un problème avec la première ligne, en particulier "data.groupby (info => info.metric)"
Je suppose que vous avez déjà une liste/un tableau de quelque class
qui ressemble à
class UserInfo {
string name;
int metric;
..etc..
}
...
List<UserInfo> data = ..... ;
Quand vous faites data.GroupBy(x => x.metric)
, cela signifie "pour chaque élément x
dans le IEnumerable défini par data
, calculez que c'est .metric
, puis regroupez tous les éléments de la même métrique dans un Grouping
et retourne un IEnumerable
de tous les groupes résultants.
<DATA> | Grouping Key (x=>x.metric) |
joe 1 01/01/2011 5 | 1
jane 0 01/02/2011 9 | 0
john 2 01/03/2011 0 | 2
jim 3 01/04/2011 1 | 3
jean 1 01/05/2011 3 | 1
jill 2 01/06/2011 5 | 2
jeb 0 01/07/2011 3 | 0
jenn 0 01/08/2011 7 | 0
il en résulterait le résultat suivant après le groupby:
(Group 1): [joe 1 01/01/2011 5, jean 1 01/05/2011 3]
(Group 0): [jane 0 01/02/2011 9, jeb 0 01/07/2011 3, jenn 0 01/08/2011 7]
(Group 2): [john 2 01/03/2011 0, jill 2 01/06/2011 5]
(Group 3): [jim 3 01/04/2011 1]
En supposant que userInfoList
est un List<UserInfo>
:
var groups = userInfoList
.GroupBy(n => n.metric)
.Select(n => new
{
MetricName = n.Key,
MetricCount = n.Count()
}
)
.OrderBy(n => n.MetricName);
La fonction lambda pour GroupBy()
, n => n.metric
signifie qu'elle obtiendra le champ metric
de chaque objet UserInfo
rencontré. Le type de n
dépend du contexte. Dans la première occurrence, il est de type UserInfo
, car la liste contient des objets UserInfo
. Dans la deuxième occurrence, n
est de type Grouping
, car il s'agit maintenant d'une liste d'objets Grouping
.
Grouping
s ont des méthodes d'extension comme .Count()
, .Key()
et à peu près tout ce que vous pouvez attendre. Tout comme vous vérifieriez .Lenght
sur un string
, vous pouvez vérifier .Count()
sur un groupe.
userInfos.GroupBy(userInfo => userInfo.metric)
.OrderBy(group => group.Key)
.Select(group => Tuple.Create(group.key, group.Count()));