[英]Nested for-loop in idiomatic JavaScript
我正在将一些代码从Python转换为JavaScript,我需要重写以下嵌套的for-loop列表理解( solution
是字符串键和列表值的字典)。
events = [e for key in solution.keys() for c in solution[key] for e in c.events]
无需多加考虑,我会将其翻译为这种笨拙,嵌套嵌套的for循环。
const events = []
for (const key of solution.keys()) {
for (const c of solution[key]) {
for (const e of c.events) {
events.push(e)
}
}
}
但是也许有更好的方法。 如何使用简短,惯用的现代(ES2015 +)JavaScript重写上述嵌套的for循环?
没有更好的方法。 原始的Python应该使用values
:
events = [e for foo in solution.values() for c in foo for e in c.events]
您可以在JavaScript中反映出来:
const events = [];
for (const foo of solution.values()) {
for (const c of foo) {
for (const e of c.events) {
events.push(e);
}
}
}
这很短并且易于阅读(或者将foo
替换为适当的名称时)。 如果您喜欢创建大量中间列表,则可以使用concat
:
const events = [];
for (const foo of solution.values()) {
for (const c of foo) {
events = events.concat(c.events);
}
}
假设solution
的值为数组,并reduce
是否喜欢不能真正节省空间或可读性的函数调用:
const events = [];
for (const foo of solution.values()) {
events = foo.reduce(
(m, n) => m.concat(n.events),
events
);
}
和Array.from
并reduce
如果您真的喜欢中间列表并且不真正喜欢可读性:
const events =
Array.from(solution.values()).reduce(
(events, foo) => events.concat(
foo.reduce(
(m, n) => m.concat(n.events),
events
)
),
[]
);
定义更多功能减轻了痛苦,但并没有改变ES6不太出色的事实
const concat = arrays =>
arrays.reduce((m, n) => m.concat(n), []);
const concatMap = (fn, arrays) =>
concat(arrays.map(fn));
const events = concatMap(
foo => concatMap(foo, c => c.events),
Array.from(solution.values())
);
也许标准库缺少一些迭代器功能
function* map(fn, iterable) {
for (const x of iterable) {
yield fn(x);
}
}
function* concat(iterables) {
for (const iterable of iterables) {
yield* iterable;
}
}
const concatMap = (fn, iterables) =>
concat(map(fn, iterables));
const events = Array.from(
concatMap(
([key, foo]) => concatMap(c => c.events, foo),
solution
)
);
老实说,坚持使用for循环。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.