loading words...

Apr 17, 2019 22:06:22

Finally, a practical use case for JavaScript generators!My draft

by @swizecteller | 368 words | 3🔥 | 116💌

Swizec Teller

Current day streak: 3🔥
Total posts: 116💌
Total words: 32303 (129 pages 📄)

JavaScript generators are amazing. A brilliant concept infinitely useful on paper.

They let you write infinite loops that terminate. Yield values from functions before they finish. Build lazy data structures. Lazy evaluation programming!

A functional programmer's wet dream. 😍

And I bet you've never used a JavaScript generator even once did you {{subscriber.first_name}}? Do you even know the syntax?

I bet you don't.

Turns out generators aren't very useful in practice. 😢

But yesterday, after years of knowing about generators, years of itching to use them, years of ... I FOUND A USE! A real world practical use-case where generators *actually* make your code better. 😱

https://youtu.be/XSHwIQUrD8E?t=1411

We were adding automatic linking of twitter usernames to my [TechLetterApp](https://techletter.app) project. Find a piece of text, parse out `@username` instances, turn into links.

Easy right?

I thought so too. Complications around inserting complex nodes into an abstract syntax tree (AST) aside, parsing those usernames is hard to do elegantly.

Unless you use generators 😛

## Here's how we did it 👇

First, you create a regex that matches `@` followed by a series of word symbols.

```javascript

const UserRegex = new RegExp(/@(\w+)/, "g");

```

Then you create a generator that runs this regex in a loop. Each `UserRegex.exec()` returns the next match.

```javascript

function* getUsernames(string) {

let match = null;

do {

match = UserRegex.exec(string);

if (match) {

yield match;

}

} while (match);

}

```

We have a `*getUsernames` generator that takes a `string`. The asterisk notation changes a function to a generator.

Inside, a loop runs as long as `match` has a value. Assigned on each iteration as a `UserRegex.exec` call.

We `yield` existing values on every loop iteration. Last one will be `null` and we don't want to return those.

Yield is how you return values from generators. Notice that even after returning a value, the generator keeps running. That's the generator magic 🧙‍♀️

You can now find all usernames in a string with a loop.

```javascript

const string = "this is a test with @swizec and @kyleshevlin, maybe @lukeed05"

for (const username of getUsernames(string)) {

console.log(username)

}

```

That outputs

```

["@swizec", "swizec"]

["@kyleshevlin", "kyleshevlin"]

["@lukeed05", "lukeed05"]

```

![](https://media.giphy.com/media/12NUbkX6p4xOO4/giphy.gif)

Here's a CodeSandbox you can play with

https://codesandbox.io/s/lr800pko5m

Cheers,

~Swizec

Originally published at twitter.com

  • 1

    @swizecteller -- nice going to rewrite this and practice- @baz - you could use this

    Brian Ball avatar Brian Ball | Apr 17, 2019 23:55:37
contact: email - twitter / Terms / Privacy