我已经习惯了Scala的“for”构造并喜欢它。我现在正在编写一些Javascript代码并使用Lo-Dash(基本上是Underscore的扩展)。有没有办法模仿Scala在javascript中的“for”理解?
我的目标是清理类似于此的map / reduce代码:
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 );
在代码中,我正在生成[[coord1,coord2,coord3],[coord4,coord5]]
格式的坐标数组,其中每个坐标为[39.5, -106.2]
(它是每个Google地图指示步骤的坐标数组。
在Scala中,同样的事情可以写成这样(如果我错了,请纠正我):
val stepCoordinates:List[List[Tuple2[Number,Number]]] = for {
leg <- legs;
step <- leg.steps;
path <- step.path;
latLng <- path
} yield (latLng.lng(), latLng.lat())
谢谢!
答案 0 :(得分:2)
Javascript无法使用新的关键字或运算符进行扩展,但这些并不重要。我们可以使用通常的功能,它们可能看起来不那么好,但非常易读。下面是一个执行嵌套for循环的函数示例。
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() + ")";
}));