My generator works not the way I want him to. Looks like simple example, but dosnt work

49 Views Asked by At

Here is a pic of console log and code

What it should do: takes a string and it should console.log separate words. What it does: it takes a string and console.log evry letter of it. And I dont understand why it does it. I'm returning the whole word with yield(I checked dst with console.log), so it should console.loged it, but in return it goes through evry letter(((( Thank you very much for your time!

scripts.js

import 'babel-polyfill';
import  {wordsCount, getWords} from './other.js';

window.addEventListener('load', function(){
        let str = '  Its a  good weather! Yeah  ! ';  

        //console.log(wordsCount(str));

        let iterator = getWords(str);
for(let some of getWords(str)){                 
        this.console.log(some);                 
        }
});

other.js

function stringClear(str)
{
        return str.trim().replace(/ {2,}/, " ");
}

export function wordsCount(str){
        return stringClear(str).split(' ').length;
}

export function* getWords(str){
        str = stringClear(str);
        let dst = "";

        for(let i = 0; i < str.length; i++)
        {
                if(str.charAt(i) == " ")
                {
                        yield* dst;
                        dst = "";
                        continue;
                }
                dst += str.charAt(i);
        }
}

console.log

I
scripts.js?6962:11 t
scripts.js?6962:11 s
scripts.js?6962:11 a
scripts.js?6962:11 g
2scripts.js?6962:11 o
scripts.js?6962:11 d
scripts.js?6962:11 w
scripts.js?6962:11 e
scripts.js?6962:11 a
scripts.js?6962:11 t
scripts.js?6962:11 h
scripts.js?6962:11 e
scripts.js?6962:11 r
scripts.js?6962:11 !
scripts.js?6962:11 Y
scripts.js?6962:11 e
scripts.js?6962:11 a
scripts.js?6962:11 h
2

There are 2 best solutions below

1
user120242 On

EDIT: I thought maybe I should explain the yield* syntax better. yield* will additionally iterate on the target yielded variable, yielding each value in the iterable. eg: yield* [1,2,3,4,5] will behave like: yield 1; yield 2; yield 3; yield 4; yield 5. This is why when you do yield* "abcd" you are getting the equivalent of yield "abcd"[0]; yield "abcd"[1]; yield "abcd"[2]; yield "abcd"[3]

Extraneous asterisk in front of the yield. You're yielding an iterator on the string you are yielding there, so each yield is additionally iterating on each word string before continuing after the yield*

window.addEventListener('load', function(){
        let str = '  Its a  good weather! Yeah  ! ';  

        //console.log(wordsCount(str));

        let iterator = getWords(str);
for(let some of getWords(str)){                 
        this.console.log(some);                 
        }
});

function stringClear(str)
{
        return str.trim().replace(/ {2,}/, " ");
}

function wordsCount(str){
        return stringClear(str).split(' ').length;
}

function* getWords(str){
        str = stringClear(str);
        let dst = "";

        for(let i = 0; i < str.length; i++)
        {
                if(str.charAt(i) == " ")
                {
                        yield dst;

                        dst = dst.slice(dst.length);
                        
                        continue;
                }
                dst += str.charAt(i);
        }
}

0
Deepak Terse On

Just change yield* dst; to yield dst; and it will be working.

I guess, that's by mistake.

But, if you happen to do it on purpose and didn't know the difference between the both, read this - https://medium.com/dailyjs/a-simple-guide-to-understanding-javascript-es6-generators-d1c350551950