2013-08-26 14 views
136

Buduję aplikację przy użyciu meteor.js i MongoDB i mam pytanie dotyczące cursor.forEach(). Chcę sprawdzić niektóre warunki na początku każdej z nich dla każdej iteracji, a następnie pomiń element, jeśli nie muszę wykonywać operacji na nim, dzięki czemu mogę zaoszczędzić trochę czasu."kontynuuj" w cursor.forEach()

Oto mój kod:

// Fetch all objects in SomeElements collection 
var elementsCollection = SomeElements.find(); 
elementsCollection.forEach(function(element){ 
    if (element.shouldBeProcessed == false){ 
    // Here I would like to continue to the next element if this one 
    // doesn't have to be processed 
    }else{ 
    // This part should be avoided if not neccessary 
    doSomeLengthyOperation(); 
    } 
}); 

wiem, mogę włączyć kursor do tablicy za pomocą cursor.find() fetch(), a następnie użyć regularne dla pętli iteracyjne nad elementami i korzystać dalej i przerwa. normalnie, ale jestem zainteresowany, jeśli jest coś podobnego do użycia w forEach().

Odpowiedz

305

Każda iteracja forEach() wywoła funkcję, którą dostarczyłeś. Aby zatrzymać dalsze przetwarzanie w ciągu każdej iteracji (i przejść do następnego elementu) po prostu trzeba return z pełnienia funkcji w odpowiednim momencie:

elementsCollection.forEach(function(element){ 
    if (!element.shouldBeProcessed) 
    return; // stop processing this iteration 

    // This part will be avoided if not neccessary 
    doSomeLengthyOperation(); 
}); 
+12

Czy wiesz, co może być "przerwa", a jeśli kontynuacja jest po prostu "powrót;". – Drag0

+4

Nie używam MongoDB, więc nie czytałem jego dokumentacji, ale możliwe, że 'return false;' będzie odpowiednikiem 'break;' (jak to jest w przypadku pętli jQuery '.each()'). Oczywiście ktokolwiek wdrożył MongoDB '.forEach()' mógł mieć inne pomysły ... – nnnnnn

+8

@ Drag0 Możesz użyć .some() jako zamiennika .forEach(), która pozwala ci zwrócić false, aby przerwać pętlę. – Andrew

4

Moim zdaniem najlepszym sposobem osiągnięcia tego celu za pomocą filtermethod ponieważ nie ma sensu wracać do bloku forEach; na przykład na swoim fragmencie:

// Fetch all objects in SomeElements collection 
var elementsCollection = SomeElements.find(); 
elementsCollection 
.filter(function(element) { 
    return element.shouldBeProcessed; 
}) 
.forEach(function(element){ 
    doSomeLengthyOperation(); 
}); 

Będzie to zawęzić elementsCollection i po prostu zachować filtred elementy, które powinny być zrealizowane.

+0

To by powtórzyło znalezione elementy dwa razy, raz w "filtrze" i drugie w "forEach", jeśli jest to duża kolekcja, będzie bardzo nieefektywne – Dementic

+0

Masz rację, ale nie sądzę, że to wielka sprawa, ponieważ złożoność czasu będzie to "O (2n)", które można uznać za "O (n)". –

+0

Uważa się, że korzystanie z SO jest używane przez innych, a nie tylko OP, zamieszczanie rozwiązań tylko w celu ich publikowania, powoduje więcej szkód niż korzyści. Powyższa odpowiedź robi to w jednej iteracji i jest "właściwą" drogą do zrobienia tego. – Dementic

Powiązane problemy