簡體   English   中英

慣用JavaScript中的嵌套for循環

[英]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.fromreduce如果您真的喜歡中間列表並且不真正喜歡可讀性:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM