2010-06-08 17 views
3

J'ai une classeLINQ: comment transformer la liste en effectuant des calculs sur chaque élément

Class MyObject 
{ 
    decimal v1; 
    decimal dv1; 
    decimal v2; 
    decimal dv2; 
} 

et

List<MyObject> ... 

je dois traiter tous les éléments de la liste en ajoutant DV1 à v1 et dv2 à v2 Quelque chose comme (pseudo-syntaxe):

myList.Transform(o=>o.v1+=o.dv1, o.v2+=o.dv2) 

Comment puis-je faire cela (évident mon pse udo-syntaxe ne fonctionne pas)?

Merci

+1

Ce n'est pas quelque chose que vous devriez faire avec LINQ. LINQ permet de faire des requêtes (= lecture seule). Vous voulez muter l'état. Vous pouvez utiliser une simple instruction foreach pour cela. – Steven

Répondre

6

Vous pouvez utiliser la méthode foreach Liste:

List<MyObject> objects = new List<MyObject>(); 

// Populate list. 

objects.ForEach(obj => { 
    obj.v1 += obj.dv1; 
    obj.v2 += obj.dv2; 
}); 
+1

La méthode 'ForEach' n'est pas une méthode d'extension sur' Enumerable', mais une méthode d'instance de 'List '. Il a été là depuis .NET 2.0. – Steven

+0

Il est trivial d'écrire une telle méthode d'extension si: ForEach public static void (cette collection IEnumerable, Action action ) { \t foreach (T objet collection) \t l'action (point); } –

+0

@Ian, trivial, mais pas nécessaire s'il a déjà une liste <>. Et sans doute, il est préférable de faire un ToList().ForEach, que de créer une méthode d'extension ambiguë (ambigu parce que la question avec IEnumerable est toujours * quand? *) – Benjol

6

LINQ est fait pour obtenir un sous-ensemble d'une énumération donnée ou pour créer une énumération avec de nouveaux types sur une liste.

Pour manipuler une liste donnée, LINQ n'est pas le bon outil pour manipuler une liste donnée. Pour faire votre tâche, vous devez prendre une boucle foreach comme

foreach(var item in objects) 
{ 
    item.v1 += obj.dv1; 
} 

Qu'est-ce que vous pouvez faire est pré-sélection, les éléments à partir d'objets que vous voulez par quelque chose comme ça

foreach(var item in object.Where(o => o.v1 % 2 == 0)) 

Comme d'autres mentionné que vous pourriez auto implémenter une méthode d'extension ForEach(), mais il existe une raison pour laquelle il n'existe pas:
Regardez Erics Blog entry.

+0

+1. Aussi: 'LINQ n'est pas le bon outil pour manipuler une liste donnée - je dirais que quelque chose comme" LINQ est fonctionnel, il n'est pas censé modifier les données d'origine mais de travailler dessus et de retourner un résultat, ou un copie des données si nécessaire ". – ANeves

0

Je ne pense pas que ce soit la tâche typique de LINQ, mais si vous voulez, vous pouvez le faire:

List<MyClass> objects = GetMyClasses(); 
Func<Action<MyClas>s, bool> do = (action) => { action(); return true; } 
(from o in objects 
where do(o, b=> { b.v1 += b.dv1; b.v2 += b.dv2; }) 
select o).ToArray(); 
2

LINQ offre 'select' for transformation

list.Select(obj => new MyObject(obj.v1 + obj.dv1, obj.dv1, obj.v2 + obj.dv2, obj.dv2)) 

Mais sachez que la valeur de retour est une nouvelle liste; les éléments de la liste d'origine ne sont pas modifiés. Pas d'effets secondaires/mutation d'état. Si tel est votre objectif, optez pour select; D'autres vont avec le pour/pour-chacun comme d'autres l'ont suggéré.

0

Merci pour toutes les réponses. Je pensais que linq peut fournir une manière élégante, mais vous avez raison - foreach fait le bon travail.