po pierwsze, Twój kod faktycznie nie iteracyjne nad listy dwa razy, to tylko iteracje raz.
Powiedziawszy, twój Select naprawdę dostaje sekwencję wszystkich indeksów; że łatwiej jest zrobić z Enumerable.Range:
var result = Enumerable.Range(0, str.Count)
.Where(i => str[i] == "avg")
.ToList();
Zrozumienie, dlaczego ta lista nie jest faktycznie powtórzyć dwukrotnie zajmie trochę przyzwyczaić. Spróbuję podać podstawowe wyjaśnienie.
Powinieneś pomyśleć o większości metod LINQ, takich jak Wybierz i Gdzie jako potok. Każda metoda wykonuje niewielką część pracy.W przypadku Select dajesz mu metodę i zasadniczo mówi: "Kiedy ktoś poprosi mnie o mój następny przedmiot, najpierw zapytam o moją sekwencję wejściową dla elementu, a następnie użyję metody, którą mam, aby przekształcić ją w coś innego, a następnie oddaj ten przedmiot komuś, kto mnie używa ". Gdzie, mniej więcej, mówi "kiedy ktoś poprosi mnie o przedmiot, zapytam o moją sekwencję wejściową dla przedmiotu, jeśli funkcja mówi, że jest dobra, przekażę go, jeśli nie, będę nadal prosić o przedmioty dopóki nie dostanę tego, który przechodzi. "
Tak więc, gdy je łączysz, to co się dzieje, ToList prosi o pierwszy przedmiot, przechodzi do Where to as to dla pierwszego przedmiotu, Where goes to Select i prosi o pierwszy przedmiot, Select idzie do listy, aby zapytać to dla jego pierwszego przedmiotu. Lista zawiera wtedy pierwszy przedmiot. Wybierz, a następnie zamień ten element na to, czego potrzebuje, aby wypluć (w tym przypadku tylko int 0) i nadaj mu wartość Where. Skąd bierze ten element i uruchamia jego funkcję, która określa, że jest prawdziwa i wypluwa 0 do ToList, co dodaje go do listy. To wszystko dzieje się jeszcze 9 razy. Oznacza to, że Select w końcu poprosi o każdy element z listy dokładnie jeden raz, i będzie podawał każdy z jego wyników bezpośrednio do Where, który będzie podawał wyniki, które "przechodzą test" bezpośrednio do ToList, który przechowuje je na liście . Wszystkie metody LINQ są starannie zaprojektowane, aby tylko raz wykonać sekwencję źródłową (gdy są one iterowane raz).
Należy zauważyć, że chociaż początkowo wydaje się to skomplikowane, w rzeczywistości jest to całkiem łatwe dla komputera. W rzeczywistości nie jest tak intensywny, jak może się wydawać na początku.
Należy zauważyć, że również ['Where'] (http://msdn.microsoft.com/en-us/library/bb549418.aspx) zapewnia to przeciążenie. –
super duper niesamowite dziękuję za to! – Jonesopolis
kod jest nieco mądrzejszy z Where - thanks Tim! – Sven