2009-07-23 7 views

Répondre

17

La clé est ici en utilisant Enumerable.GroupBy et la méthode d'agrégation Enumerable.Count:

List<int> list = new List<int>() { 1,1,2,2,3,4,5 }; 

// group by value and count frequency 
var query = from i in list 
      group i by i into g 
      select new {g.Key, Count = g.Count()}; 

// compute the maximum frequency 
int whatsTheFrequencyKenneth = query.Max(g => g.Count); 

// find the values with that frequency 
IEnumerable<int> modes = query 
           .Where(g => g.Count == whatsTheFrequencyKenneth) 
           .Select(g => g.Key); 

// dump to console 
foreach(var mode in modes) { 
    Console.WriteLine(mode); 
} 
+10

+1 pour le nom de la variable –

+0

Merci, juste m'a aidé sur le même problème –

+0

Notez que cela peut exploser lorsque la liste d'entrée est vide. Cela peut ou peut ne pas être désiré. De plus, ne répétez-vous pas deux fois la requête? un pour 'Max' et un pour la sélection finale? – nawfal

1
from num in a 
group num by num into numg 
let c = numg.Count() 
order by c descending 
select new { Number = numg.Key, Count = c } 
+1

Cela ne se commande que par fréquence et calcule la fréquence. Cependant, il ne trouve pas le ou les éléments qui se sont le plus produits. – jason

3

La réponse de Jason est correct, mais vous pouvez effectuer cette opération dans un LINQ opération.

 List<int> list = new List<int>() { 1, 1, 2, 2, 3, 4, 5 }; 

     // return most frequently occurring items 
     var query = from i in list 
        group i by i into g 

        let maxFreq = (from i2 in list 
            group i2 by i2 into g2 
            orderby g2.Count() descending 
            select g2.Count()).First() 

        let gCount = g.Count() 

        where gCount == maxFreq 

        select g.Key; 

     // dump to console 
     foreach (var mode in query) 
     { 
      Console.WriteLine(mode); 
     } 
0

Je pense que le nombre le plus fréquent peut également être réalisé en une seule requête comme this-

var query = (from i in list 
       group i by i into g 
       orderby g.Count() descending 
       select new { Key = g.Key, Count = g.Count() }).FirstOrDefault(); 
    if (query == null) Console.WriteLine("query = NULL"); 
    else Console.WriteLine("The number '{0}' occurs {1} times.", query.Key, query.Count); 

chèque nul n'est pas vraiment nécessaire, mais il peut être utile lorsque nulle est effectivement prévu (comme vide liste)

+1

Cette méthode n'attrape pas les listes comportant plusieurs éléments ayant la fréquence la plus élevée. – jason

2
public static Tres MostCommon<Tsrc, Tres>(this IEnumerable<Tsrc> source, Func<Tsrc, Tres> transform) 
{ 
    return source.GroupBy(s => transform(s)).OrderByDescending(g => g.Count()).First().Key; 
} 

Et dans votre exemple avec des types intégrés vous pouvez l'appeler comme:

List<int> a = new List<int>{ 1,1,2,2,3,4,5 }; 
int mostCommon = a.MostCommon(x => x); 
Questions connexes