Tout d'abord, votre code ne fait itérer sur la liste deux fois, il ne une fois itère.
Cela dit, votre Select est en train d'obtenir une séquence de tous les index; qui est plus facile à faire avec Enumerable.Range:
var result = Enumerable.Range(0, str.Count)
.Where(i => str[i] == "avg")
.ToList();
Comprendre pourquoi la liste ne sont pas en fait deux fois réitérée prendra un certain temps pour s'y habituer. Je vais essayer de donner une explication de base.
Vous devriez penser à la plupart des méthodes LINQ, telles que Select et Where en tant que pipeline. Chaque méthode fait un tout petit peu de travail.Dans le cas de Select, vous lui donnez une méthode, et il dit essentiellement: "Chaque fois que quelqu'un me demande mon prochain article, je vais d'abord demander ma séquence d'entrée pour un article, puis utiliser la méthode que j'ai pour le convertir en quelque chose d'autre. puis donnez cet objet à quiconque m'utilise. " Où, plus ou moins, dit, "chaque fois que quelqu'un me demande un article je vais demander ma séquence d'entrée pour un article, si la fonction dit que c'est bon, je vais le transmettre, sinon je vais continuer à demander des articles jusqu'à ce que j'en reçoive un qui passe. " Donc, quand vous les enchaînez, ce qui se passe, c'est que ToList demande le premier élément, il va à Où pour son premier élément, Où va à Sélectionner et lui demande son premier élément, Sélectionner va à la liste pour demander pour son premier article. La liste fournit ensuite son premier élément. Select transforme ensuite cet élément en ce qu'il doit cracher (dans ce cas, juste l'int 0) et le donne à Where. Où prend cet élément et exécute sa fonction qui détermine que c'est vrai et donc crache 0 à ToList, qui l'ajoute à la liste. Toute cette chose arrive ensuite plus de 9 fois. Cela signifie que Select finira par demander chaque élément de la liste une seule fois, et qu'il transmettra chacun de ses résultats directement à Where, ce qui alimentera les résultats qui "passent le test" directement à ToList, qui les stocke dans une liste. . Toutes les méthodes LINQ sont soigneusement conçues pour ne jamais répéter la séquence source qu'une fois (quand elles sont itérées une fois). Notez que, bien que cela vous semble compliqué au début, il est assez facile pour l'ordinateur de faire tout cela. Ce n'est pas aussi performant que cela puisse paraître au premier abord.
Notez également que ['Where'] (http://msdn.microsoft.com/en-us/library/bb549418.aspx) fournit cette surcharge. –
super duper génial merci pour ça! Code – Jonesopolis
est un peu plus intelligent avec Où - merci Tim! – Sven