技术控

    今日:160| 主题:49347
收藏本版 (1)
最新软件应用技术尽在掌握

[其他] ES6 Iterators and Generators: 6 Exercises and Solutions

[复制链接]
残梦Dangerou 发表于 2016-11-28 08:34:44
8 2

立即注册CoLaBug.com会员,免费获得投稿人的专业资料,享用更多功能,玩转个人品牌!

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
This article is a section from the workbook of ES6 in Practice. I created this course during the last couple of months, because there is an evident need for a resource that helps JavaScript developers put theory into practice.
  This course won’t waste your time with long hours of video, or long pages of theory that you will never use in practice. We will instead focus on learning just enough theory to solve some exercises. Once you are done with the exercises, you can check the reference solutions, and conclude some lessons. In fact, some of the theory are sometimes placed in the reference solutions.
  If you like this article, check out the course    here.  
  In mylast article, I gave you six exercises. Today, you can check the reference solution.  
  Exercise 1.What happens if we use a string iterator instead of an iterable object in a    for-ofloop?  
  1.  
  2. letmessage = 'ok';
  3. letmessageIterator = message[Symbol.iterator]();
  4.  
  5. messageIterator.next();
  6.  
  7. for ( letitemofmessageIterator ) {
  8.     console.log( item );
  9. }
  10.  
复制代码
Solution:Similarly to generators, in case of strings, arrays, DOM elements, sets, and maps, an iterator object is also an iterable.  
  Therefore, in the    for-ofloop, the remaining    kletter is printed out.  
  Exercise 2.Create a countdown iterator that counts from 9 to 1. Use generator functions!  
  1.  
  2. letgetCountdownIterator = // Your code comes here
  3.  
  4. console.log( [ ...getCountdownIterator() ] );
  5. > [9, 8, 7, 6, 5, 4, 3, 2, 1]
  6.  
复制代码
Solution:

  1.  
  2. letgetCountdownIterator = function *() {
  3.     let i = 10;
  4.     while( i > 1 ) {
  5.         yield --i;
  6.     }
  7. }
  8.  
  9. console.log( [ ...getCountdownIterator() ] );
  10. > [9, 8, 7, 6, 5, 4, 3, 2, 1]
  11.  
复制代码
The generator function yields the numbers    9to    1. The spread (    ...) operator consumes all values. Then the generator function returns    undefined, ending the iteration process.  
  Exercise 3.Make the following object iterable:  
  1.  
  2. lettodoList = {
  3.     todoItems: [],
  4.     addItem( description ) {
  5.         this.todoItems.push( { description, done: false } );
  6.         return this;
  7.     },
  8.     crossOutItem( index ) {
  9.         if ( index < this.todoItems.length ) {
  10.             this.todoItems[index].done = true;
  11.         }
  12.         return this;
  13.     }
  14. };
  15.  
  16. todoList.addItem( 'task 1' ).addItem( 'task 2' ).crossOutItem( 0 );
  17.  
  18. letiterableTodoList = // ???;
  19.  
  20. for ( letitemofiterableTodoList ) {
  21.     console.log( item );
  22. }
  23.  
  24. // Without your code, you get the following error:
  25. // Uncaught TypeError: todoList[Symbol.iterator] is not a function
  26.  
复制代码
First Solution (well known symbol):

  We could use well known symbols to make    todoListiterable. We can add a    *[Symbol.iterator]generator function that yields the elements of the array. This will make the    todoListobject iterable, yielding the elements of    todoItemsone by one.  
  1.  
  2. lettodoList = {
  3.     todoItems: [],
  4.     *[Symbol.iterator]() {
  5.         yield* this.todoItems;
  6.     }
  7.     addItem( description ) {
  8.         this.todoItems.push( { description, done: false } );
  9.         return this;
  10.     },
  11.     crossOutItem( index ) {
  12.         if ( index < this.todoItems.length ) {
  13.             this.todoItems[index].done = true;
  14.         }
  15.         return this;
  16.     }
  17. };
  18.  
  19. letiterableTodoList = todoList;
  20.  
复制代码
Second solution (generator function): If you prefer staying away from well known symbols, it is possible to make your code more semantic:  
  1.  
  2. lettodoList = {
  3.     todoItems: [],
  4.     addItem( description ) {
  5.         this.todoItems.push( { description, done: false } );
  6.         return this;
  7.     },
  8.     crossOutItem( index ) {
  9.         if ( index < this.todoItems.length ) {
  10.             this.todoItems[index].done = true;
  11.         }
  12.         return this;
  13.     }
  14. };
  15.  
  16. todoList.addItem( 'task 1' ).addItem( 'task 2' ).crossOutItem( 0 );
  17.  
  18. lettodoListGenerator = function *() {
  19.     yield* todoList.todoItems;
  20. }
  21.  
  22. letiterableTodoList = todoListGenerator();
  23.  
复制代码
The first solution reads a bit like a hack. The second solution looks cleaner even if you have to type more characters.
  Exercise 4.Determine the values logged to the console without running the code. Instead of just writing down the values, formulate your thought process and explain to yourself how the code runs line by line.  
  1.  
  2. leterrorDemo = function *() {
  3.     yield 1;
  4.     throw 'Error yielding the next result';
  5.     yield 2;
  6. }
  7.  
  8. letit = errorDemo();
  9.  
  10. // Execute one statement at a time to avoid
  11. // skipping lines after the first thrown error.
  12.  
  13. console.log( it.next() );
  14.  
  15. console.log( it.next() );
  16.  
  17. console.log( [...errorDemo()] );
  18.  
  19. for ( letelementoferrorDemo() ) {
  20.     console.log( element );
  21. }
  22.  
复制代码
Solution:

  1.  
  2. console.log( it.next() );
  3. > Object {value: 1, done: false}
  4.  
  5. console.log( it.next() );
  6. > UncaughtErroryieldingthenextresult
  7.  
  8. console.log( [...errorDemo()] );
  9. > UncaughtErroryieldingthenextresult
  10.  
  11. for ( letelementoferrorDemo() ) {
  12.     console.log( element );
  13. }
  14. > Object {value: 1, done: false}
  15. > UncaughtErroryieldingthenextresult
  16.  
复制代码
We created three iterables in total:    it, one in the statement in the spread operator, and one in the    for-ofloop.  
  In the example with the    nextcalls, the second call results in a thrown error.  
  In the spread operator example, the expression cannot be evaluated, because an error is thrown.
  In the    for-ofexample, the first element is printed out, then the error stopped the execution of the loop.  
  Exercise 5.Create an infinite sequence that generates the next value of the Fibonacci sequence.  
  The Fibonacci sequence is defined as follows:
  
       
  •       fib( 0 ) = 0   
  •       fib( 1 ) = 1   
  • for      n > 1,      fib( n ) = fib( n - 1 ) + fib( n - 2 )  
  Solution:

  1.  
  2. function *fibonacci() {
  3.     let a = 0, b = 1;
  4.     yield a;
  5.     yield b;
  6.     while( true ) {
  7.         [a, b] = [b, a+b];
  8.         yield b;
  9.     }
  10. }
  11.  
复制代码
Note that you only want to get the    next()element of an infinite sequence. Executing    [...fibonacci()]will skyrocket your CPU usage, speed up your CPU fan, and then crash your browser.  
  Exercise 6.Create a lazy    filtergenerator function. Filter the elements of the Fibonacci sequence by keeping the even values only.  
  1.  
  2. function *filter( iterable, filterFunction ) {
  3.     // insert code here
  4. }
  5.  
复制代码
Solution:

  1.  
  2. letgetCountdownIterator = // Your code comes here
  3.  
  4. console.log( [ ...getCountdownIterator() ] );
  5. > [9, 8, 7, 6, 5, 4, 3, 2, 1]
  6.  
  7. 0
复制代码
Notice how easy it is to combine generators and lazily evaluate them.
  1.  
  2. letgetCountdownIterator = // Your code comes here
  3.  
  4. console.log( [ ...getCountdownIterator() ] );
  5. > [9, 8, 7, 6, 5, 4, 3, 2, 1]
  6.  
  7. 1
复制代码
Lazy evaluation is essential when we work on a large set of data. For instance, if you have 1000 accounts, chances are that you don’t want to transform all of them if you just want to render the first ten on screen. This is when lazy evaluation comes into play.
友荐云推荐




上一篇:pbxprojHelper--Xcode工程文件助手
下一篇:Structuring data with Logstash
酷辣虫提示酷辣虫禁止发表任何与中华人民共和国法律有抵触的内容!所有内容由用户发布,并不代表酷辣虫的观点,酷辣虫无法对用户发布内容真实性提供任何的保证,请自行验证并承担风险与后果。如您有版权、违规等问题,请通过"联系我们"或"违规举报"告知我们处理。

刘徐 发表于 2016-11-28 12:29:57
沙发不是你想抢,想抢就能抢!
回复 支持 反对

使用道具 举报

feixiang222 发表于 2016-11-28 17:11:21
不要羡慕,不要崇拜,更不要粉我,feixiang222不是归人,只是过客
回复 支持 反对

使用道具 举报

*滑动验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

我要投稿

推荐阅读

扫码访问 @iTTTTT瑞翔 的微博
回页顶回复上一篇下一篇回列表手机版
手机版/CoLaBug.com ( 粤ICP备05003221号 | 文网文[2010]257号 )|网站地图 酷辣虫

© 2001-2016 Comsenz Inc. Design: Dean. DiscuzFans.

返回顶部 返回列表