I've gotten used to Scala's "for" construct and like it a lot. I am now writing some JavaScript code and am using Lodash (basically an extension of Underscore). Is there any way to mimic Scala's "for" comprehension in JavaScript?
My goal is to clean map/reduce code similar to this:
var rawCoordinates = _.map( directionsRoute.legs, function ( leg ) {
return _.map( leg.steps, function ( step ) {
return _.map( step.path, function ( latLng ) {
return [ latLng.lng(), latLng.lat() ];
} );
} );
} );
var finalCoordinates = _.flatten( rawCoordinates, true );
In the code, I'm producing an array of coordinates in the format [[coord1,coord2,coord3],[coord4,coord5]], where each coordinate is [39.5, -106.2] (it is an array of the coordinates of each Google Maps directions step).
In Scala, this same thing could be written like this:
val stepCoordinates:List[List[Tuple2[Number,Number]]] = for {
leg <- legs;
step <- leg.steps;
path <- step.path;
latLng <- path
} yield (latLng.lng(), latLng.lat())
Thanks!
Javascript can't be extended with new keywords or operators, but those are not vital. We can live with usual functions, they may look not that nice, but pretty readable. Below is an example of a function that performs nested for loops.
function deepMap(xs, path, fn) {
function impl(xs, path, args) {
var result = new Array(xs.length);
if (path.length == 0) {
for (var i = 0; i < xs.length; i++) {
result[i] = fn.apply(null, args.concat([xs[i]]));
}
return result;
} else {
for (var i = 0; i < xs.length; i++) {
result[i] = impl(xs[i][path[0]], path.slice(1), args.concat(xs[i]));
}
return result.reduce(function(x, y) {return x.concat(y)}, []);
}
}
return impl(xs, path, []);
}
// for generating lat and long functions
function x(x) {return function() {return x}}
// sample data
var legs = [{
steps: [{
path: [{lat: x(1), lng: x(2)}]
}, {
path: [{lat: x(2), lng: x(3)}]
}]
}, {
steps: [{
path: [{lat: x(3), lng: x(4)}]
}, {
path: [{lat: x(4), lng: x(5)}]
}]
}];
// prints [ '(1, 2)', '(2, 3)', '(3, 4)', '(4, 5)' ]
console.log(deepMap(legs, ['steps', 'path'], function(leg, step, ll) {
return "(" + ll.lat() + ", " + ll.lng() + ")";
}));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With