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.
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 );
});
0
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.
0
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:
- MDN Array Map
- MDN Array Reduce
1