Skip to content

Instantly share code, notes, and snippets.

@toshi0383
Created April 4, 2019 02:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save toshi0383/b3f464b14755bc48310decb506fe3731 to your computer and use it in GitHub Desktop.
Save toshi0383/b3f464b14755bc48310decb506fe3731 to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
c1 := asChan(1, 3, 5, 7)
c2 := asChan(2, 4, 6, 8)
c := combineLatest(c1, c2)
for v := range c {
fmt.Println(v)
}
time.Sleep(time.Duration(rand.Intn(1000)) * time.Millisecond)
for v := range c {
fmt.Println(v)
}
}
type Tuple struct {
v0 interface{}
v1 interface{}
}
func combineLatest(a <-chan interface{}, b <-chan interface{}) <-chan Tuple {
var lasta interface{} = nil
var lastb interface{} = nil
c := make(chan Tuple)
go func() {
defer close(c)
for a != nil || b != nil {
select {
case v, ok := <-a:
if !ok {
a = nil
continue
}
lasta = v
if lastb != nil {
c <- Tuple{v0: v, v1: lastb}
}
case v, ok := <-b:
if !ok {
b = nil
continue
}
lastb = v
if lasta != nil {
c <- Tuple{v0: lasta, v1: v}
}
}
}
}()
return c
}
func asChan(vs ...int) <-chan interface{} {
c := make(chan interface{})
go func() {
for i, v := range vs {
c <- v
if i < len(vs)-1 {
time.Sleep(time.Duration(rand.Intn(1000)) * time.Millisecond)
}
}
close(c)
}()
return c
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment