From 1e52e1902fe43a24d0c653c6f4f193aaaf1565d5 Mon Sep 17 00:00:00 2001 From: Michal Vyskocil Date: Sun, 25 Feb 2024 22:04:47 +0100 Subject: [PATCH] Problem: break the chain example different from an actual code Solution: use becca to sync an actual code. --- README.md | 76 ++++++++++++++++++++++++++++++++++++++++----------- README.md.tpl | 22 +++------------ ideas_test.go | 8 ++++-- 3 files changed, 70 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index e1f89a8..a63710b 100644 --- a/README.md +++ b/README.md @@ -371,25 +371,69 @@ Some crazy and not so crazy ideas to expolse ## break the chain -One of the coolest (keep in mind it was a late night one) ideas may be +One of the coolest (keep in mind it was a late night one) ideas may be breaking +the chain. The prototype exists in ideas_test.go, just not sure if it _is_ +actually a good idea. It is definitely doable and possible in Go. ```go - n := []string{...} - chain := it.NewChain(n).Filter().Something().Seq() - // break the chain implementing a part as a for range loop - for s, err := range chain { - n, err := strconv.Atoi(s) - if err != nil { - break - } - // do the magic here and resume the chain - magicYield(n) - } - - Map(magicSeq, foo).Filter(bar).Slice() -``` +package it_test + +import ( + "fmt" + + "github.com/gomoni/it" +) + +type pusher struct { + stack chan string +} + +func (y *pusher) push(s string) { + y.stack <- s +} -Implemented in break_da_chain example test in `ideas_test.go`. +func (y pusher) seq() func(func(string) bool) { + return func(yield func(string) bool) { + for { + select { + case s, open := <-y.stack: + if !open || !yield(s) { + return + } + } + } + } +} + +func (y pusher) wait() { + <-y.stack +} + +func Example_break_da_chain() { + n := []string{"aa", "aaa", "aaaaaaa", "a"} + + // create a method chain + chain := it.NewChain(it.From(n)). + Filter(func(s string) bool { return true }) + + // break it - with some syntax sugar + p := pusher{stack: make(chan string)} + defer p.wait() + go func() { + defer close(p.stack) + for s := range chain.Seq() { + p.push(s) + } + }() + + // continue here + chain2 := it.NewChain(p.seq()). + Filter(func(s string) bool { return len(s) > 2 }) + slice := chain2.Slice() + fmt.Println(slice) + // Output: [aaa aaaaaaa] +} +``` ## make iterations context aware????? diff --git a/README.md.tpl b/README.md.tpl index efbd43a..b3b8508 100644 --- a/README.md.tpl +++ b/README.md.tpl @@ -166,25 +166,11 @@ Some crazy and not so crazy ideas to expolse ## break the chain -One of the coolest (keep in mind it was a late night one) ideas may be +One of the coolest (keep in mind it was a late night one) ideas may be breaking +the chain. The prototype exists in ideas_test.go, just not sure if it _is_ +actually a good idea. It is definitely doable and possible in Go. -```go - n := []string{...} - chain := it.NewChain(n).Filter().Something().Seq() - // break the chain implementing a part as a for range loop - for s, err := range chain { - n, err := strconv.Atoi(s) - if err != nil { - break - } - // do the magic here and resume the chain - magicYield(n) - } - - Map(magicSeq, foo).Filter(bar).Slice() -``` - -Implemented in break_da_chain example test in `ideas_test.go`. +{{ "Example_break_da_chain" | example }} ## make iterations context aware????? diff --git a/ideas_test.go b/ideas_test.go index 6900324..44d1209 100644 --- a/ideas_test.go +++ b/ideas_test.go @@ -34,9 +34,11 @@ func (y pusher) wait() { func Example_break_da_chain() { n := []string{"aa", "aaa", "aaaaaaa", "a"} + // create a method chain chain := it.NewChain(it.From(n)). Filter(func(s string) bool { return true }) + // break it - with some syntax sugar p := pusher{stack: make(chan string)} defer p.wait() go func() { @@ -46,8 +48,10 @@ func Example_break_da_chain() { } }() - chain2 := it.NewChain(p.seq()) + // continue here + chain2 := it.NewChain(p.seq()). + Filter(func(s string) bool { return len(s) > 2 }) slice := chain2.Slice() fmt.Println(slice) - // Output: [aa aaa aaaaaaa a] + // Output: [aaa aaaaaaa] }