I have an app which gets data from the database (MongoDB) in JSON format. The returned data contains nested arrays and I want to access the values in the nested arrays. The returned JSON format looks like this:
[
{"_id": "81724587125","name": "Object 1", "arrayOne":["1","2","3"]},
{"_id": "87687687687","name": "Object 2", "arrayOne":["4","5","6"]}
]
Now what I want is to retrieve the values from arrayOne
from all objects and push them into a single array like so:
combinedValues:["1","2","3","4","5","6"]
To achieve this I have used Nested For Loops below is my actual code:
function myFunc(result){
$scope.clients = [];
for(var i = 0; i < result.length; i++){
for(var x = 0; x < result[i].sectorClients.length; x++){
$scope.clients.push(result[i].sectorClients[x]);
}
}
};
The above code works fine and does what I want it to do.
My Question:
Is using nested for loops for this particular situation a good programming practice? Is there a better way of achieving the same functionality? Ive heard people say that nested for loops can be "expensive" processing wise.
-
You can write MapReduce query to get the same result directly from Mongo.Mahdi– Mahdi2016年03月14日 10:03:26 +00:00Commented Mar 14, 2016 at 10:03
-
@Mahdi Thank you for the comment. Thats good advice I'll have look into that now. Do you have an example links that might be helpful?Lorenzo von Matterhorn– Lorenzo von Matterhorn2016年03月14日 10:06:35 +00:00Commented Mar 14, 2016 at 10:06
-
1Any MapReduce tutorial on Mongo should get you started.Mahdi– Mahdi2016年03月14日 10:22:21 +00:00Commented Mar 14, 2016 at 10:22
-
Nested for loops typically aren't expensive. But, of course, saying they're 'not expensive' is as subjective as saying they are. Depends what you're doing inside the loop, or what you're iterating over. In your case, it's fine.JᴀʏMᴇᴇ– JᴀʏMᴇᴇ2016年03月14日 11:46:03 +00:00Commented Mar 14, 2016 at 11:46
4 Answers 4
As I mentioned in the comments you can get the same result directly from MongoDB using a MapReduce
query; However a cleaner JavaScript equivalent for your nested loops can be something like this:
var data = [
{"_id": "81724587125","name": "Object 1", "arrayOne":["1","2","3"]},
{"_id": "87687687687","name": "Object 2", "arrayOne":["4","5","6"]}
];
var result = data.reduce(function (previousValue, currentValue, currentIndex, array) {
return previousValue.arrayOne.concat( currentValue.arrayOne );
});
Nested loops are expensive when they both iterate over independent data in a "criss-cross" fashion, because they may represent a O(n^2) algorithm that can be made more efficient. You may think of such loops as describing the program "for every element in X, loop over every element in Y again".
This is not one of those cases. Your data are an array of objects, each containing further arrays of objects. A nested loop here is not only fine: it's completely expressive and appropriate.
in the case, you needn't use "puth" function, push every tiny element into the array;because you can operate the whole array eg: [1,2,3].concat([4,5,6]) => [1, 2, 3, 4, 5, 6]
then you can improve your code by reducing the loop
You can use map function of array to get the properties (arrayOne
) you want, and create a flattened array from array of arrays (array of arrayOne
s) using reduce.
var clients = results
.map(function(r){ return r.arrayOne; })
.reduce(function(prev, curr) { return prev.concat(curr); }, []);
// ["1", "2", "3", "4", "5", "6"]
Resources:
-
1This seems like only a slight variation on the solution already provided in the accepted answer, but without addressing the conceptual question the OP asked. Keep in mind that unlike StackOverflow, questions here on on Programmers.SE are rarely looking for a specific piece of code.Ixrec– Ixrec2016年03月18日 14:42:09 +00:00Commented Mar 18, 2016 at 14:42