Looping through data sets with Go Channels

Tom Elliott
Jul 1, 2018 · 2 min read
Image for post
Image for post

Repeatedly iterating through multiple sets of data together can be a tricky proposition, leading to nested loops or difficult to follow logic. Luckily, channels in Go can help decompose this problem into

Let’s say you’re setting up QA of your online store application, and want to generate some test orders. For the sake of simplicity, let’s assume that you can only order one product at a time. An order may look something like this:

type Order struct {
AccountID int
ProductID int
}

We have three Accounts and Five products.

+-----------+-------+
| AccountID | Name |
+-----------+-------+
| 1 | Alice |
| 3 | Bob |
| 7 | Carol |
+-----------+-------+
+-----------+------------+-------+
| ProductID | Name | Price |
+-----------+------------+-------+
| 719 | Apple | 0.75 |
| 822 | Banana | 1.20 |
| 1024 | Cherry | 0.10 |
| 1179 | Damson | 0.80 |
| 2001 | Elderberry | 0.55 |
+-----------+------------+-------+

A function to generate 100 orders with rotating values of AccountID and ProductId may look like this:

Which produces orders of the form:

[{AccountID:1 ProductID:719},
{AccountID:3 ProductID:822},
{AccountID:7 ProductID:1024},
{AccountID:1 ProductID:1179},
{AccountID:3 ProductID:2001},
{AccountID:7 ProductID:719},
...]

This is reasonable concise, but lines 9 and 10 are a bit tricky to follow and have a high risk of typos — like using len(accountIDs) on line 10 which would result in only a subset of the product IDs to be used. Additionally, if the IDs are provided from a stream rather than an up-front slice, there would be a need for additional logic to reset as needed.

We can refactor this to move the responsibility for looping through IDs to a goroutine:

This function iterates through the provided data forever, and since the write to the output channel blocks until read, values will only be created as required. The createOrders function can then accept channels as parameters:

This results in a simpler, easy to read createOrders function, which is also independent of the source of the input data. Goroutines are cheap, so use of channels doesn’t have to be limited to concurrency.

average-coder

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store