8
votes

Comment ajouter deux listes dans LINQ SO-ADCONNEDLIST [x] = listone [x] + listtwo [x]?

Je veux ajouter deux listes d'un type numérique tel que Listone [x] + ListTwo [x]

La sortie de la liste doit être un générique.Inérable que je peux utiliser dans les futures requêtes LINQ. P>

Bien que j'ai pu le faire en utilisant le code ci-dessous, je ne peux pas m'empêcher de vous sentir comme il doit y avoir une meilleure façon. Des idées? P>

List<int> firstList = new List<int>(new int[] { 1, 3, 4, 2, 5, 7, 2, 5, 7, 8, 9, 0 });
List<int> secondList = new List<int>(new int[] { 4, 6, 8, 3, 1, 5, 9, 3, 0 });

int findex = 0;

ILookup<int, int> flookup = firstList.ToLookup(f =>
                            {
                               int i = findex;
                               findex++; 
                               return i;
                               }, p => p);  

var listsAdded = from grp in flookup
                 select grp.First() + secondList.ElementAtOrDefault(grp.Key);

foreach (int i in listsAdded)
  Console.WriteLine(i);


2 commentaires

Que se passe-t-il lorsque la deuxième liste est plus longue que la première?


@gabe - voir ma solution ci-dessous, il gère des listes de longueur différente.


3 Réponses :


5
votes
var result = 
   from i in 
        Enumerable.Range(0, Math.Max(firstList.Count, secondList.Count))
   select firstList.ElementAtOrDefault(i) + secondList.ElementAtOrDefault(i);

5 commentaires

Ceci est exactement ce que je cherchais. Merci Artem.


AVERTISSEMENT - Cette approche peut être terriblement inefficace - en particulier pour les listes de toute taille significative. Chaque appel à ELEMENTATORDEFAULT peut avoir besoin de itérer la liste depuis le début. La combinaison de deux listes de 100 éléments peut entraîner le coût d'itération de 10 100 éléments plutôt que de seulement 200. Pour 1000 éléments, il devient 1 001 000 éléments. Et cela s'aggrave rapidement de là ...


@Enigmativity, ce n'est pas vrai dans le contexte donné. Considérant que l'élémenatordefault s'appelle la liste (ilist en général) - la taille de la liste n'a pas vraiment d'importance car ce que l'élémenatordefault (index) appelle en interne liste [index] qui accède à la liste des tableaux internes de la liste par index, donc l'accès est O (1) et ne pas itération de rien comme vous dites. L'ÉlentaeTordefault peut se comporter comme si vous avez indiqué pour ceux Iénumérables qui ne sont pas de type (mais ce n'est pas le cas de cette question).


Je suis d'accord avec toi. Veuillez noter que j'ai dit "... peut avoir besoin d'itérer ..." et non "a besoin de itérer". La question originale a donné un exemple en utilisant IList <> , mais néanatomess le ellementatordefault est une méthode d'extension de iEnumerable <> pourquoi je pensais mon avertissement était valide. Êtes-vous pas d'accord?


@Enigmativité, je conviens que votre avertissement est valide pour iEnumerable <>, je viens de mentionner que votre avertissement "n'est pas vrai dans le contexte donné". Vous avez dit "... Peut-être besoin d'itérer la liste ...", mais n'a pas clarifié quand et pourquoi j'ai donc décidé de donner des éclaircissements.



3
votes

On dirait que vous voulez une fonction comme ceci: xxx


1 commentaires

Merci gabe. Cet IA est un excellent exemple d'une extension qui résoudrait mon problème. J'espérais pouvoir faire cela sans écrire une extension, comme l'a fait Artem. Votre exemple d'extension a été instructif cependant, et j'ai aimé votre façon de gérer les longueurs de la liste différentes. Merci de votre aide.



21
votes

Ce que vous cherchez est une méthode zip. Cette méthode vous permet de combiner les listes de longueur égale dans une seule liste en appliquant une projection.

Par exemple P>

var sumList = firstList.Zip(secondList, (x,y) => x + y).ToList();


2 commentaires

Comment gérer les séquences de taille différentes?


@gabe, différentes implémentations prennent des itinéraires différents. La version BCL ignorera les éléments supplémentaires sur la liste plus longue, mais il est assez facile d'écrire une méthode différente qui étend la liste.