2017-01-25 8 views
0

いくつかのコードをPythonからJavaScriptに翻訳しています。次のネストされたfor-loop list comprehension(ここではsolutionは文字列キーとリスト値の辞書です)を書き直す必要があります。熟語JavaScriptのネストされたfor-loop

events = [e for key in solution.keys() for c in solution[key] for e in c.events] 

これをあまり考えずに、私はこの扱いにくい、醜いネストされたfor-loopのようなものに翻訳したいと思います。

const events = [] 

for (const key of solution.keys()) { 
    for (const c of solution[key]) { 
     for (const e of c.events) { 
      events.push(e) 
     } 
    } 
} 

しかし、多分もっと良い方法があります。上記のネストされたfor-loopを、短い、慣用的な現代的な(ES2015 +)JavaScriptで書き直すにはどうすればよいですか?

答えて

1

もっと良い方法はありません。オリジナルのPythonはvaluesを使用する必要があります。

あなたはJavaScriptで反映させることができ
events = [e for foo in solution.values() for c in foo for e in c.events] 

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); 
    } 
} 

reduce本当にsolutionの値を仮定して、スペースや読みやすさを保存しない関数呼び出しのようなあなたが配列されている場合:

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()) 
); 

はたぶん標準ライブラリは、forループで、いくつかのイテレータ機能

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 
    ) 
); 

スティックが欠落しているそれほど大きくないという事実は変わりません正直なところ。

+0

非常に徹底した解答です。ありがとうございました! – faviouz

関連する問題