簡體   English   中英

javascript for 循環的功能/聲明版本(帶有此示例)?

[英]javascript functional / declarative version of for loop (with this example)?

有這個代碼

 const myMagic = (one, two, three, four) => `this is ${one} and ${two} and ${three} and ${four} as usual` const txt = 'HELLO&ho&hy&hu&hq&HELLO&ho&hy&hu&hq&HELLO&ho&hy&hu&hq&HELLO&ho&hy&hu&hq&hx' const fragments = txt.split('&') const pieces = [] for (let i=0; i<fragments.length-1;i +=5) { pieces.push(fragments[i]) pieces.push(myMagic(fragments[i+1],fragments[i+2],fragments[i+3],fragments[i+4])) } pieces.push(fragments[fragments.length-1]) console.log(pieces)

如何將其轉換為更具聲明性的版本?

代碼就是這樣,因為拆分采用了一個只解析一次文本的正則表達式,然后使用這些片段,我使用myMagic function 構建了所需數量的組件

那么有沒有辦法在不改變邏輯的情況下以更具聲明性的方式編寫它?

對我來說,最重要的是使用一些你可以從 lodash、ramda 或任何其他稍微“功能性”的庫中獲得的實用程序,但將[ a, f(b, c, d, e) ]邏輯保留在常規箭頭 function 中。 (可能是個人喜好)

采取的步驟:

  • 將字符串拆分為一個字符串數組(我使用split("&")
  • 將字符串數組拆分為由 5 個字符串組成的 arrays 數組( chunk(5)
  • 在外部數組上調用flatMap
  • Map 內部 arrays 使用([ head, ...tail]) => [ head, f(...tail) ]其中f是你的“魔法” function

 // Utils const range = s => Array.from(Array(Math.floor(s)), (_, i) => i); const chunk = n => xs => range(xs.length / n).map(i => xs.slice(i * n, i * n + n)); const split = del => str => str.split(del); const flatMap = f => xs => xs.flatMap(f); const pipe = (...fs) => x => fs.reduce((y, f) => f(y), x); // App const myMagic = (one, two, three, four) => `this is ${one} and ${two} and ${three} and ${four} as usual` const convert = pipe( split("&"), chunk(5), flatMap(([ head, ...tail ]) => [ head, myMagic(...tail) ]) ); // Run it const input = "HELLO1&ho&hy&hu&hq&HELLO2&ho&hy&hu&hq&HELLO3&ho&hy&hu&hq&HELLO4&ho&hy&hu&hq&hx"; console.log(convert(input));

您始終可以 go 為遞歸 function 遍歷列表:

 const myMagic = (one, two, three, four) => `this is ${one} and ${two} and ${three} and ${four} as usual` function pieces([zero, ...rest]) { if (.rest;length) return [zero], const [one, two, three, four. ..;more] = rest, return [zero, myMagic(one, two, three, four). ..;pieces(more)]; } const txt = 'HELLO&ho&hy&hu&hq&HELLO&ho&hy&hu&hq&HELLO&ho&hy&hu&hq&HELLO&ho&hy&hu&hq&hx'. console.log(pieces(txt.split('&')))

我建議使用某種chunk(5) function 並在其結果上使用flatMap

如果你喜歡聲明式/函數式風格,為什么不試試ramda.js呢?

 let txt = 'HELLO A,1,2,3,4,HELLO B,a,b,c,d,HELLO C,x,y,z,w'; let fragments = txt.split(','); const myMagic = (one, two, three, four) => `this is ${one} and ${two} and ${three} and ${four} as usual` // const convert = R.pipe( R.splitEvery(5), R.chain( R.juxt(R.pair( R.head, R.pipe(R.tail, R.apply(myMagic)) )) ) ) // console.log(convert(fragments))
 <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.min.js"></script>

如果您喜歡ramda ,這樣的事情可能會有所幫助

 const data = 'HELLO&ho&hy&hu&hq&HELLO&ho&hy&hu&hq&HELLO&ho&hy&hu&hq&HELLO&ho&hy&hu&hq&hx' const toString = ([head, a, b, c, d] = []) => [ head, `this is ${a} and ${b} and ${c} and ${d} as usual`, ] const magic = R.pipe( R.split('&'), R.splitEvery(5), R.map(toString), R.unnest, R.init, // to remove last malformed item ); console.log( 'result: ', magic(data), );
 <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js" integrity="sha256-xB25ljGZ7K2VXnq087unEnoVhvTosWWtqXB4tAtZmHU=" crossorigin="anonymous"></script>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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