2010-12-04 65 views
91

J'ai une liste d'objets. Une propriété de l'entrée d'objet individuel est le montant. Comment puis-je obtenir la somme du montant?C# Liste d'objets, comment obtenir la somme d'une propriété

Si ma liste était de type double, je peux être en mesure de faire quelque chose comme ceci:

double total = myList.Sum(); 

Cependant, je veux quelque chose de semblable à cela, mais cette syntaxe est incorrecte.

double total = myList.amount.Sum(); 

Comment est-ce que je devrais accomplir ceci? J'adorerais utiliser la fonction Sum si possible au lieu de boucler et de calculer la valeur.

Répondre

181
using System.Linq; 

...

double total = myList.Sum(item => item.Amount); 
+8

Est-ce plus rapide que foreach par intérêt? – Coops

+3

Je suis également intéressé par la question de @ CodeBlend. Ce calcul sera-t-il plus rapide qu'une boucle for? – rex

+4

Assurez-vous d'avoir une instruction using pour System.Linq – ADH

26

Et si vous avez besoin de le faire sur les articles qui correspondent à une condition spécifique ...

double total = myList.Where(item => item.Name == "Eggs").Sum(item => item.Amount); 
-2

Voici un exemple de code que vous pouvez exécuter pour faire tel test:

var f = 10000000; 
var p = new int[f]; 

for(int i = 0; i < f; ++i) 
{ 
    p[i] = i % 2; 
} 

var time = DateTime.Now; 
p.Sum(); 
Console.WriteLine(DateTime.Now - time); 

int x = 0; 
time = DateTime.Now; 
foreach(var item in p){ 
    x += item; 
} 
Console.WriteLine(DateTime.Now - time); 

x = 0; 
time = DateTime.Now; 
for(int i = 0, j = f; i < j; ++i){ 
    x += p[i]; 
} 
Console.WriteLine(DateTime.Now - time); 

Le même exemple r objet complexe est:

void Main() 
{ 
    var f = 10000000; 
    var p = new Test[f]; 

    for(int i = 0; i < f; ++i) 
    { 
     p[i] = new Test(); 
     p[i].Property = i % 2; 
    } 

    var time = DateTime.Now; 
    p.Sum(k => k.Property); 
    Console.WriteLine(DateTime.Now - time); 

    int x = 0; 
    time = DateTime.Now; 
    foreach(var item in p){ 
     x += item.Property; 
    } 
    Console.WriteLine(DateTime.Now - time); 

    x = 0; 
    time = DateTime.Now; 
    for(int i = 0, j = f; i < j; ++i){ 
     x += p[i].Property; 
    } 
    Console.WriteLine(DateTime.Now - time); 
} 

class Test 
{ 
    public int Property { get; set; } 
} 

Mes résultats avec les optimisations du compilateur off sont:

00:00:00.0570370 : Sum() 
00:00:00.0250180 : Foreach() 
00:00:00.0430272 : For(...) 

et second test sont:

00:00:00.1450955 : Sum() 
00:00:00.0650430 : Foreach() 
00:00:00.0690510 : For() 

il ressemble à LINQ est généralement plus lent que foreach (...) mais ce qui est bizarre pour moi, c'est que foreach (...) semble être plus rapide que pour la boucle.

+1

pour référence future, regardez 'Stopwatch' dans' System.Diagnostics' car il s'agit d'un enregistreur de temps haute performance. (Je ne vous ai pas downvote btw) –

+1

N'utilisez pas 'DateTime.Now' pour mesurer. Il a une performance terrible car il retourne toujours l'heure locale. 'DateTime.UtcNow' est plus rapide; cependant, il n'utilise toujours pas une résolution aussi élevée que la classe 'Stopwatch'. – taffer

+2

Cela ne répond pas à la question. –

4

Une autre alternative:

myPlanetsList.Select(i => i.Moons).Sum(); 
+1

Au lieu de '' '.Select (i => i.Moons) .Sum()' '' vous pouvez utiliser '' '.Sum (i => i.Moons)' '' – Mason

+1

@Mason, à droite et c'est comment Alex a abordé le problème dans sa réponse précédente, donc j'ai juste fourni une manière différente de faire la même chose. – usefulBee

+1

Ah oui, désolé pour mon idée fausse. – Mason