[英]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.