简体   繁体   中英

iterate over a collection in meteor using nested loop of “ forEach ”

I will start with a small description of the result I want to get:

Let's imagine we have a collection called " Elements " which contains the 4 documents: 'a','b','c' and 'd'. I want to iterate over " Elements " and insert in a new collection called " Queries " the pairs :

(a,b);(a,c);(a,d);(b,a);(b,c)...(d,a);(d,b);(d,c). => which means " Queries " will contain (in this example) 4*3 = 12 pairs of elements (documents) at the end.

Here is the code I'm using (it's a method in meteor server triggered by a click on a button):

'Queries': function() {
    var allElements = Elements.find();
    allElements.forEach(function(myLeftElement){ //First forEach
        allElements.forEach(function(myRightElement){// Nested forEach
            if(myLeftElement._id !== myRightElement._id){
                Queries.insert( {myLeftElement : myLeftElement._id, myRightElement : myRightElement._id} );
            }
        }); //End Of nested forEach
    }); //End Of First forEach
}

In fact it works only for the first "myLeftElement" with all other elements "myRightElement" but stops there: it inserts, into "Queries" collection, the pairs: [(a,b);(a,c) and (a,d)] and then stops.

Since I am a beginner in web developement in general and in using Meteor in particular, I am seeking for your help.

1) I need to understand why once the nested cursor method "forEach" stops, the whole function stops.

2) How can I improve the code to get the result I really want: to every element of my collection "myLeftElement" there is a forEach method that creates pairs with all other elements "myRightElement". And then moves to the next "myLeftElement" and do the same till the end.

Thanks,

Here is a working example of iterating over an Array with vanilla JavaScript that gets the expected result:

 var elements = ['a', 'b', 'c', 'd']; var result = []; elements.forEach(function(item) { // Create a copy of the current array to work with var elements_copy = elements.slice(0); var temp_array = []; /* Delete the current `item` from the array since we don't want duplicate 'a:a' items in the array. IMPORTANT: There are better ways of doing this, see: http://stackoverflow.com/questions/3954438/remove-item-from-array-by-value */ elements_copy.splice(elements_copy.indexOf(item), 1); elements_copy.forEach(function(child_item) { temp_array.push(item + "," + child_item); }); result.push(temp_array); }); console.log(result); 

You'll need to make sure you open the Console in the Developer Tools to see the result.

When you're starting out I recommend getting working scenarios with the least complexity -- like here where I removed Meteor and Mongo out of the picture -- to ensure that your logic is sound then working in the rest from there.

So, to answer your questions directly:

  1. Unsure of why it is stopping as I'm unable to recreate
  2. Example provided should suffice -- but I'm sure there is a better way

Hope that helps!

The @cynicaljoy's answer inspired me in two ways:

  • using arrays
  • and a better way of deleting duplicate 'a:a' items in the arrays (by visiting the link he provided).

So thanks a lot.

Now after taking the necessary modifications, here is one solution that actually works fine using Meteor and Mongodb codes:

'Queries' : function() {

var allElements = Elements.find().map(function(item){return item._id} ); /* this returns an array of item._id of all elements*/
var totalItems = allElements.length;
var itemsCounter = 0;
var withoutLeftItem;
   while(itemsCounter < totalItems){
      withoutLeftItem=_.without(allElements,allElements[itemsCounter] ); /*The function _.without(array, *items) used in underscore.js returns array with specified items removed */    
      withoutLeftItem.forEach(function(myRightElement){
         Queries.insert( {myLeftElement : allElements[itemsCounter], myRightElement : myRightElement} );
      });
   itemsCounter++;
   }
 }

I am still curious to understand why the solution presented in the question was not working as it was supposed and also to see an optimized code in terms of memory usage.

Hope this helps other people. Thanks all

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM