Tout d'abord, votre code n'itère pas deux fois sur la liste, il ne l'itère qu'une fois.
Cela dit, votre Select
ne fait que récupérer une séquence de tous les index ; cela est plus facile à faire avec la fonction Enumerable.Range
:
var result = Enumerable.Range(0, lst1.Count)
.Where(i => lst1[i] == "a")
.ToList();
Il faudra s'habituer à comprendre pourquoi la liste n'est pas itérée deux fois. Je vais essayer de donner une explication de base.
Vous devez considérer la plupart des méthodes LINQ, telles que Select et Where, comme un pipeline. Chaque méthode effectue une petite partie du 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 élément, je vais d'abord demander un élément à ma séquence d'entrée, puis utiliser la méthode dont je dispose pour le convertir en quelque chose d'autre, et enfin donner cet élément à celui qui m'utilise". Where
plus ou moins, c'est dire : "chaque fois que quelqu'un me demande un article, je demande à ma séquence d'entrée un article, si la fonction dit qu'il est bon, je le transmets, sinon je continue à demander des articles jusqu'à ce que j'en obtienne un qui passe".
Donc, quand vous les enchaînez, ce qui se passe est ToList
demande le premier élément, il va à Where
pour son premier article, Where
va à Select
et lui demande son premier élément, Select
va à la liste pour lui demander son premier élément. La liste fournit alors 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
. Where
prend cet élément et exécute sa fonction qui détermine que c'est vrai et renvoie donc 0
a ToList
qui l'ajoute à la liste. Tout cela se reproduit encore 9 fois. Cela signifie que Select
finira par demander chaque élément de la liste exactement une fois, et il transmettra chacun de ses résultats directement à Where
qui transmet 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 n'itérer qu'une seule fois la séquence source (lorsqu'elles sont itérées une fois).
Notez que, même si cela vous semble compliqué au premier abord, l'ordinateur n'a en fait aucun mal à faire tout cela. Les performances ne sont pas aussi élevées qu'il n'y paraît au premier abord.