Giter VIP home page Giter VIP logo

koazee's Introduction

Build Status Go Report Card godoc codecov Awesome

Koazee

Lazy like a koala, smart like a chimpanzee

What is Koazee?

Koazee is a StreamLike, Immutable, Lazy Loading and smart Golang Library to deal with slices.

Visit the Koazee wiki to find out what Koazee can do.

Koazee Highlights

  • Immutable: Koazee won't modify your inputs. 
  • StreamLike: We can combine operations up our convenience. 
  • Lazy loading: Operations are not performed until they're required
  • Generic: Koazee provides a generic interface able to deal with slice of any type without creating custom functions.
  • Focusing on performance: First rule for implementing a new operation is providing the best possible performance.

Getting started

Installing

Add Koazee to your project

Go modules

module github.com/me/project
require ( 
  github.com/wesovilabs/koazee vX.Y.Z
)

Glide

glide get github.com/wesovilabs/koazee

Go dep

go get github.com/wesovilabs/koazee

Usage

Stream creation

Let's first obtain a stream from an existing array.

package main

import (
	"fmt"
	"github.com/wesovilabs/koazee"
)

var numbers = []int{1, 5, 4, 3, 2, 7, 1, 8, 2, 3}

func main() {
	fmt.Printf("slice: %v\n", numbers)
	stream := koazee.StreamOf(numbers)
	fmt.Printf("stream: %v\n", stream.Out().Val())
}

/**
go run main.go

slice: [1 5 4 3 2 7 1 8 2 3]
stream: [1 5 4 3 2 7 1 8 2 3]
*/

Stream operations

Current release v0.0.3 (Gibbon) brings us 20 generic operations that are showed below

stream.At / stream.First / stream.Last

These operations return an element from the stream

package main

import (
	"fmt"
	"github.com/wesovilabs/koazee"
)

var numbers = []int{1, 5, 4, 3, 2, 7, 1, 8, 2, 3}

func main() {
	stream := koazee.StreamOf(numbers)
	fmt.Printf("stream.At(4): %d\n", stream.At(4).Int())
	fmt.Printf("stream.First: %d\n", stream.First().Int())
	fmt.Printf("stream.Last: %d\n", stream.Last().Int())
}

/**
go run main.go

stream.At(4): 2
stream.First: 1
stream.Last: 3
*/
stream.Add / stream.Drop / stream.DropWhile / stream.DeleteAt / stream.Pop / stream.Set

These operations add or delete elements from the stream.

package main

import (
	"fmt"
	"github.com/wesovilabs/koazee"
)

var numbers = []int{1, 5, 4, 3, 2, 7, 1, 8, 2, 3}

func main() {
	fmt.Printf("input: %v\n", numbers)

	stream := koazee.StreamOf(numbers)
	fmt.Print("stream.Add(10): ")
	fmt.Println(stream.Add(10).Do().Out().Val())

	fmt.Print("stream.Drop(5): ")
	fmt.Println(stream.Drop(5).Do().Out().Val())
	
	fmt.Print("stream.DropWhile(val<=5): ")
	fmt.Println(stream.DropWhile(func(element int)bool{return element<=5}).Do().Out().Val())

	fmt.Print("stream.DeleteAt(4): ")
	fmt.Println(stream.DeleteAt(4).Do().Out().Val())

	fmt.Print("stream.Set(0,5): ")
	fmt.Println(stream.Set(0, 5).Do().Out().Val())

	fmt.Print("stream.Pop(): ")
	val, newStream := stream.Pop()
	fmt.Printf("%d ... ", val.Int())
	fmt.Println(newStream.Out().Val())

}

/**
go run main.go

input: [1 5 4 3 2 7 1 8 2 3]
stream.Add(10): [1 5 4 3 2 7 1 8 2 3 10]
stream.Drop(5): [1 4 3 2 7 1 8 2 3]
stream.DropWhile(val<=5): [7 8]
stream.DeleteAt(4): [1 5 4 3 7 1 8 2 3]
stream.Set(0,5): [5 5 4 3 2 7 1 8 2 3]
stream.Pop(): 1 ... [5 4 3 2 7 1 8 2 3]
*/
tream.Count / stream.IndexOf / stream.IndexesOf / stream.LastIndexOf / stream.Contains

These operations return info from the elements in the stream

package main

import (
	"fmt"
	"github.com/wesovilabs/koazee"
)

var numbers = []int{1, 5, 4, 3, 2, 7, 1, 8, 2, 3}

func main() {
	fmt.Printf("input: %v\n", numbers)
	stream := koazee.StreamOf(numbers)
	count, _ := stream.Count()
	fmt.Printf("stream.Count(): %d\n", count)
	index, _ := stream.IndexOf(2)
	fmt.Printf("stream.IndexOf(2): %d\n", index)
	indexes, _ := stream.IndexesOf(2)
    fmt.Printf("stream.IndexesOf(2): %d\n", indexes)
	index, _ = stream.LastIndexOf(2)
	fmt.Printf("stream.LastIndexOf(2): %d\n", index)
	contains, _ := stream.Contains(7)
	fmt.Printf("stream.Contains(7): %v\n", contains)
}

/**
go run main.go

input: [1 5 4 3 2 7 1 8 2 3]
stream.Count(): 10
stream.IndexOf(2): 4
stream.IndexesOf(2): [4 8]
stream.LastIndexOf(2): 8
stream.Contains(7): true
*/
stream.Sort / stream.Reverse

These operations organize the elements in the stream.

package main

import (
	"fmt"
	"github.com/wesovilabs/koazee"
	"strings"
)

var animals = []string{"lynx", "dog", "cat", "monkey", "fox", "tiger", "lion"}

func main() {
	fmt.Print("input: ")
	fmt.Println(animals)
	stream := koazee.StreamOf(animals)

	fmt.Print("stream.Reverse(): ")
	fmt.Println(stream.Reverse().Out().Val())

	fmt.Print("stream.Sort(strings.Compare): ")
	fmt.Println(stream.Sort(strings.Compare).Out().Val())

}

/**
go run main.go

input: [lynx dog cat monkey fox tiger lion]
stream.Reverse(): [lion tiger fox monkey cat dog lynx]
stream.Sort(strings.Compare): [cat dog fox lion lynx monkey tiger]
*/
stream.Take / stream.Filter / stream.RemoveDuplicates

These operations return a filtered stream.

package main

import (
	"fmt"
	"github.com/wesovilabs/koazee"
)

var animals = []string{"lynx", "dog", "cat", "monkey", "dog", "fox", "tiger", "lion"}

func main() {
	fmt.Print("input: ")
	fmt.Println(animals)
	stream := koazee.StreamOf(animals)

	fmt.Print("stream.Take(1,4): ")
	fmt.Println(stream.Take(1, 4).Out().Val())

	fmt.Print("stream.Filter(len==4): ")
	fmt.Println(stream.
		Filter(
			func(val string) bool {
				return len(val) == 4
			}).
		Out().Val(),
	)
	fmt.Print("stream.RemoveDuplicates(): ")
	fmt.Println(stream.RemoveDuplicates().Out().Val())
}

/**
go run main.go

input: [lynx dog cat monkey dog fox tiger lion]
stream.Take(1,4): [dog cat monkey dog]
stream.Filter(len==4): [lynx lion]
stream.RemoveDuplicates(): [lynx dog cat monkey fox tiger lion]
*/
stream.GroupBy

This operation creates groups depending on the returned function value

You can now optionally return an error as the second parameter to stop processing of the stream. The error will be available in stream.Out().Err().UserError().

package main

import (
	"fmt"
	"github.com/wesovilabs/koazee"
	"strings"
)

var animals = []string{"lynx", "dog", "cat", "monkey", "dog", "fox", "tiger", "lion"}

func main() {
	fmt.Printf("input: %v\n", animals)
	stream := koazee.StreamOf(animals)
	fmt.Print("stream.GroupBy(strings.Len): ")
	out, _ := stream.GroupBy(func(val string)int{return len(val)})
	fmt.Println(out)
}

/**
go run main.go

input: [lynx dog cat monkey dog fox tiger lion]
stream.GroupBy(strings.Len): map[5:[tiger] 4:[lynx lion] 3:[dog cat dog fox] 6:[monkey]]
*/
stream.Map

This operation performs a modification over all the elements in the stream.

You can now optionally return an error as the second parameter to stop processing of the stream. The error will be available in stream.Out().Err().UserError().

package main

import (
	"fmt"
	"github.com/wesovilabs/koazee"
	"strings"
)

var animals = []string{"lynx", "dog", "cat", "monkey", "dog", "fox", "tiger", "lion"}

func main() {
	fmt.Printf("input: %v\n", animals)
	stream := koazee.StreamOf(animals)
	fmt.Print("stream.Map(strings.Title): ")
	fmt.Println(stream.Map(strings.Title).Do().Out().Val())
}

/**
go run main.go

input: [lynx dog cat monkey dog fox tiger lion]
stream.Map(strings.Title): [Lynx Dog Cat Monkey Dog Fox Tiger Lion]
*/
stream.Reduce

This operation give us a single output after iterating over the elements in the stream.

You can now optionally return an error as the second parameter to stop processing of the stream. The error will be available in stream.Out().Err().UserError().

package main

import (
	"fmt"
	"github.com/wesovilabs/koazee"
)

var numbers = []int{1, 5, 4, 3, 2, 7, 1, 8, 2, 3}

func main() {
	fmt.Printf("input: %v\n", numbers)
	stream := koazee.StreamOf(numbers)
	fmt.Print("stream.Reduce(sum): ")
	fmt.Println(stream.Reduce(func(acc, val int) int {
		return acc + val
	}).Int())
}

/**
go run main.go

input: [1 5 4 3 2 7 1 8 2 3]
stream.Reduce(sum): 36
*/
stream.ForEach

This operation iterates over the element in the stream.

You can now optionally return an error as the second parameter to stop processing of the stream. The error will be available in stream.Out().Err().UserError().

package main

import (
	"fmt"
	"github.com/wesovilabs/koazee"
)

type message struct {
	user    string
	message string
}

var messages = []*message{
	{user: "John", message: "Hello Jane"},
	{user: "Jane", message: "Hey John, how are you?"},
	{user: "John", message: "I'm fine! and you?"},
	{user: "Jane", message: "Me too"},
}

func main() {

	stream := koazee.StreamOf(messages)
	stream.ForEach(func(m *message) {
		fmt.Printf("%s: \"%s\"\n", m.user, m.message)
	}).Do()
}

/**
go run main.go

John: "Hello Jane"
Jane: "Hey John, how are you?"
John: "I'm fine! and you?"
Jane: "Me too"
*/

Combine operations and evaluate them lazily

The main goal of Koazee is providing a set of operations that can be combined and being evaluated lazily.

package main

import (
	"fmt"
	"github.com/wesovilabs/koazee"
	"strings"
)

type Person struct {
	Name string
	Male bool
	Age  int
}

var people = []*Person{
	{"John Smith", true, 32},
	{"Peter Pan", true, 17},
	{"Jane Doe", false, 20},
	{"Anna Wallace", false, 35},
	{"Tim O'Brian", true, 13},
	{"Celia Hills", false, 15},
}

func main() {
	stream := koazee.
		StreamOf(people).
		Filter(func(person *Person) bool {
			return !person.Male
		}).
		Sort(func(person, otherPerson *Person) int {
			return strings.Compare(person.Name, otherPerson.Name)
		}).
		ForEach(func(person *Person) {
			fmt.Printf("%s is %d years old\n", person.Name, person.Age)
		})

	fmt.Println("Operations are not evaluated until we perform stream.Do()\n")
	stream.Do()
}

/**
go run main.go

Operations are not evaluated until we perform stream.Do()

Anna Wallace is 35 years old
Celia Hills is 15 years old
Jane Doe is 20 years old
 */

Available Operations

Operation Description Since
Add It adds a new element in the last position v0.0.1
At It returns the element in the given position v0.0.1
Contains It checks if the given element is found in the stream. v0.0.1
Count It returns the number of elements in a stream v0.0.1
DeleteAt It remove the elements in the given position v0.0.3
Drop It removes an element from the stream v0.0.1
DropWhile It removes the elements in the stream that match with the given input function v0.0.4
Filter It discards those elements that doesn't match with the provided filter v0.0.1
First It returns the element in the first position v0.0.1
ForEach It does something over all the elements in the stream. v0.0.1
GroupBy It creates groups depending on the returned function value v0.0.4
IndexOf It returns the first index of the element in the stream. v0.0.3
IndexesOf It returns the index for all the occurrences of the element in the stream. v0.0.4
Last It returns the element in the last position v0.0.1
LastIndexOf It returns the last occurrence for the element in the stream. v0.0.3
Map It converts the element in the stream v0.0.1
Pop It extracts the first element in the stream and return this and the new stream v0.0.3
Reduce It reduceshe stream to a single value by executing a provided function for each value of the stream v0.0.1
RemoveDuplicates It removes duplicated elements. v0.0.1
Reverse It reverses the sequence of elements in the stream. v0.0.3
Set It replaces the element in the given index by the provided value v0.0.3
Sort It sorts the elements in the stream v0.0.1
Take It returns a stream with the elements between the given indexes v0.0.3

Samples

A rich and growing set of examples can be found on koazee-samples

Benchmark

You can check the Benchmark for the Koazee operations here

A benchmark comparison with other frameworks can be found in Koazee vs Go-Funk vs Go-Linq

Guides & Tutorials

Shopping cart with Koazee

Roadmap

This is only the beginning! By the way, If you missed any operation in Koazee v0.0.3, or you found a bug, please create a new issue on Github or vote the existing ones!

Contributors

koazee's People

Contributors

15cm avatar flowonyx avatar glassonion1 avatar ifraixedes avatar ivancorrales avatar somen440 avatar u5surf avatar xuyz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

koazee's Issues

operation chunk

This operation will split the stream in several streams with the given size

func Chunk(size index)[]stream.Stream

koazee reduce wont accept the subsequent function param values or state outside the reduce function

Ex :

type test struct {
	name string
}

func test33(names []string, test test ) string{
	stream := koazee.StreamOf(names).
		Reduce(func(acc string, name string) (string, error) {

			log.Info( test.name)

			return acc, nil
		})



	return stream.Val().(string)

}

func main() {
	test1 := test{
		name:"name1",
	}

	test2 := test{
		name:"name2",
	}

	array := []string{"33","44"}
	test33(array,test1)
	test33(array,test2)
}

output :-

name1
name1
name1
name1

Expected :-

name1
name1
name2
name2

A free variable seems to be cached badly within ForEach

I am afraid I found a bug in koazee v0.0.3.
Try the following code:

package main

import (
	"fmt"
	"github.com/wesovilabs/koazee"
)

func main() {
	for i := 0; i < 2; i++ {
		numbers := koazee.StreamOf([]int{1, 2, 3})
		n := 0
		numbers.ForEach(func(num int) {
			fmt.Println("n = ", n, " and num = ", num)
			n += num // koazee's bug: n seems to be cached badly.
		}).Do()
		fmt.Println("n = ", n)
	}
}

I have got the following result:

$ go version
go version go1.11.4 darwin/amd64
$ go run koazeeBug.go
n =  0  and num =  1
n =  1  and num =  2
n =  3  and num =  3
n =  6
n =  6  and num =  1
n =  7  and num =  2
n =  9  and num =  3
n =  0

In the last line of output, n should be 6.
The expected output is as follows:

n =  0  and num =  1
n =  1  and num =  2
n =  3  and num =  3
n =  6
n =  0  and num =  1
n =  1  and num =  2
n =  3  and num =  3
n =  6

The free variable n within the function argument of ForEach seems to be cached badly.

Operation filterWithIndex

It should be nice provide a filter operation in which beside of the value the index is provided.This could look like

koazee.StreamOf([]string{"a","b"}.FilterWithIndex(func(index int, val string)bool{return true})

IndexesOf operation

IndexesOf(val interface{}) []int,err

For example,

myStream:= koazee.StreamOf([]int{3,4,2,5,2,1,6,2})
output:=myStream.IndexesOf(2)
fmt.Println(output)
// []int {2,4,7}

Maybe another name for the operation?

Out() function should perform Do()

Curently when we want to perform the stream opeations we need to do something like

fmt.Println(stream.Drop(5).Do().Out().Val())

it would be nice if we just need to do

fmt.Println(stream.Drop(5).Out().Val())

Operation While

Provide a new operation while.While(sentinelFunc() bool, do func())

koazee-gen must be improved

Organize code in repository koazee-gen and provide a tool that can be performed by any other developer.

https://github.com/wesovilabs/koazee-gen

Currently the project is only hosted to show how koazee avoid reflection when deals with primitive types, but it would be nice make koazee-gen like a tool easily to run from any developer in their own local machines.

dropRight operation

This operations will be used to drop elements in the steam on the right of the given element

var elements = []int{10,12,7,41,5,6}
res:=koazee.StreamOf(elements).DropRight(12).Out().Val()
fmt.Println(res)

// [10,12]

Map operation with index

It should be nice provide a filter operation in which beside of the value the index is provided.This could look like

koazee.StreamOf([]string{"a","b"}.Map(func(index int, val string)int{return len(val)})

New operations DropAt and AddAt

This operations would be used to add an element in a given position or delete de element in the stream in a given position

Map() throws panic on empty stream

Describe the bug
Map() throws panic if stream is empty or was filtered out

To Reproduce
This code taken from examples. Just added Map():

package main

import (
	"strings"

	"github.com/wesovilabs/koazee"
)

type Person struct {
	Name string
	Male bool
	Age  int
}

var people = []*Person{
	{"John Smith", true, 32},
}

func main() {
	stream := koazee.
		StreamOf(people).
		Filter(func(person *Person) bool {
			return !person.Male
		}).
		Sort(func(person, otherPerson *Person) int {
			return strings.Compare(person.Name, otherPerson.Name)
		}).
		Map(func(person *Person) *string {
			return &person.Name
		})

	stream.Out().Val()
}

Expected behavior
Should be no errors. Map() shall be skipped for empty streams

Current behaviour

panic: reflect: slice index out of range

goroutine 1 [running]:
reflect.Value.Index(0x65e9a0, 0xc000004540, 0x97, 0x0, 0x65d860, 0x196, 0x2030000)
	***/go/src/reflect/value.go:939 +0x1ee
github.com/wesovilabs/koazee/internal/maps.(*Map).validate(0xc00007b9b8, 0x40c801, 0xc68bff426f1e59c0)
	***/go/pkg/mod/github.com/wesovilabs/[email protected]/internal/maps/map.go:91 +0x817
github.com/wesovilabs/koazee/internal/maps.(*Map).Run(0xc00007b9b8, 0x4985b8, 0xc00007b968, 0x6e7d50, 0x0)
	***/go/pkg/mod/github.com/wesovilabs/[email protected]/internal/maps/map.go:21 +0x4a
github.com/wesovilabs/koazee/stream.(*streamMap).run(0xc000044220, 0x65e9a0, 0xc000004540, 0x65e9a0, 0xc000004540, 0x97, 0x717a00, 0x6549a0, 0x0, 0x0, ...)
	***/go/pkg/mod/github.com/wesovilabs/[email protected]/stream/map.go:13 +0xff
github.com/wesovilabs/koazee/stream.Stream.run(0x65e9a0, 0xc000004540, 0x65e9a0, 0xc000004540, 0x97, 0x717a00, 0x6549a0, 0x0, 0x0, 0xc00014e020, ...)
	***/go/pkg/mod/github.com/wesovilabs/[email protected]/stream/stream.go:162 +0xa0
github.com/wesovilabs/koazee/stream.Stream.run(0x65e9a0, 0xc000004540, 0x65e9a0, 0xc000004540, 0x97, 0x717a00, 0x6549a0, 0x0, 0x0, 0xc00014e020, ...)
	***/go/pkg/mod/github.com/wesovilabs/[email protected]/stream/stream.go:167 +0x13a
github.com/wesovilabs/koazee/stream.Stream.run(0x65e9a0, 0xc000004540, 0x65e9a0, 0xc000004540, 0x97, 0x717a00, 0x6549a0, 0x0, 0x0, 0xc00014e010, ...)
	***/go/pkg/mod/github.com/wesovilabs/[email protected]/stream/stream.go:167 +0x13a
github.com/wesovilabs/koazee/stream.Stream.Out(0x65e9a0, 0xc0000044a0, 0x65e9a0, 0xc0000044a0, 0x97, 0x717a00, 0x6549a0, 0x1, 0x0, 0xc00014e000, ...)
	***/go/pkg/mod/github.com/wesovilabs/[email protected]/stream/out.go:35 +0x5c
main.main()
	***/main.go:32 +0x28c

Process finished with exit code 2

Version - v0.0.5

DropWhile operation

DropWhile(func(interface{})bool) stream.Stream

For example,

myStream:= koazee.StreamOf([]int{3,4,5,2,1,6})
output:=myStream.DropWhile( func(val int)bool{
       return val <=4
}).Do().Out().Val()
fmt.Println(output)
// []int {5,6)}

go get: error loading module requirements

go get -u github.com/wesovilabs/koazee
go: finding github.com/golangci/unparam latest
go: finding github.com/golangci/revgrep latest
go: finding github.com/divan/depscheck latest
go: finding github.com/go-critic/checkers latest
go: finding github.com/golangci/gofmt latest
go: finding github.com/golangci/check latest
go: finding github.com/golangci/lint latest
go: finding golang.org/x/tools latest
go: finding github.com/golangci/ineffassign latest
go: finding github.com/shurcooL/go latest
go: finding github.com/golangci/lint-1 latest
go: finding github.com/shirou/w32 latest
go: finding github.com/shurcooL/go-goon latest
go: finding golang.org/x/crypto latest
go: finding github.com/golangci/maligned latest
go: finding github.com/golangci/errcheck latest
go: finding github.com/golangci/goconst latest
go: finding github.com/golangci/prealloc latest
go: finding gopkg.in/check.v1 latest
go: finding github.com/OpenPeeDeeP/depguard latest
go: finding github.com/golangci/gosec latest
go: finding github.com/golangci/tools latest
go: finding golang.org/x/sys latest
go: finding github.com/nbutton23/zxcvbn-go latest
go: finding github.com/golangci/go-misc latest
go: sourcegraph.com/sourcegraph/[email protected]: parsing go.mod: unexpected module path "github.com/sourcegraph/go-diff"
go: finding golang.org/x/net latest
go: finding github.com/mitchellh/go-ps latest
go: finding github.com/golangci/go-tools latest
go: finding mvdan.cc/unparam latest
go get: error loading module requirements

"sourcegraph.com/sourcegraph/go-diff" can not be found

Koazee GroupBY shouldn't return a reflect.Value

There's an issue when operation groupBy is performed.

This operation should return a value like other operation do but it's returnint a reflect.Value

v.Interface() shouldn't be required in the example below

package main

import (
	"fmt"
	"github.com/wesovilabs/koazee"
)

type Person struct {
	Fullname string
	Age      int
}

var people = []Person{
	{"John Doe", 25},
	{"Jane Doe", 25},
	{"Tom Doe", 22},
	{"David Doe", 15},
}

func main() {
	v,_:=koazee.StreamOf(people).GroupBy(func(p Person) int{
		return p.Age
	})
	fmt.Println(v.Interface().(map[int][]Person))
}

Documentation

Deploy library documentation by making use of Jekyll or Hugo .

Documentation must be ready before launching first release 0.0.1

Providing more functions to take an array without casting it

Support more clever responses for operations,

Currently we can make use of Int(), Int32(), float64(),.... when we want to take the output value from the stream, and then we don't need to cast the result,

It would be nice if Koazee provided us with the same function for arrays, kind of

Our code would look like below

package main

import (
	"github.com/wesovilabs/koazee"
	"github.com/wesovilabs/koazee/logger"
)

var numbers = []int{1, 2, 3, 4, 4, 1}

func main() {
	logger.Enabled = true
	koazee.Stream().
		With(numbers).
		Filter(func(val int) bool {
			return val%2 == 0
		}).
		Map(func(val int) int {
			return val * 2
		}).
		RemoveDuplicates().
		Out().IntArray()
}

Append operation

Concat(val []interface{}) stream.Stream

For example,

myStream:= koazee.StreamOf([]int{3,4,2,5,2,1,6,2})
output:=myStream.Append([]int{5,4})
fmt.Println(output)
// []int {3,4,2,5,2,1,6,2,5,2}

DropLeft operation

var elements = []int{10,12,7,41,5,6}
res:=koazee.StreamOf(elements).DropLeft(12).Out().Val()
fmt.Println(res)

// [10]

operation Set

func Set(index int,value interface{}) stream.Stream

Set operation must be inmutable

One of the principle of Koazee is that the elements are inmutable: It means that the input will never be modified by Koazee...

Set operations is modifying the input as it can be observed in this example.

package main

import (
	"fmt"
	"github.com/wesovilabs/koazee"
)

var numbers = []int{1, 5, 4, 3, 2, 7, 1, 8, 2, 3}

func main() {
	fmt.Printf("input: %v\n", numbers)

	stream := koazee.StreamOf(numbers)

	fmt.Print("stream.Set(0,5): ")
	fmt.Println(stream.Set(0, 5).Do().Out().Val())
	fmt.Printf("input: %v\n", stream.Out().Val())

}

input: [1 5 4 3 2 7 1 8 2 3]
stream.Set(0,5): [5 5 4 3 2 7 1 8 2 3]
input: [5 5 4 3 2 7 1 8 2 3]

This need to be fixed to release v0.0.3

After the filter, the stream is 0 and the map cannot be recognized as 0

val := koazee.StreamOf(bindSlice)
out := val.Filter(func(x model.ZbizThirdLogin) bool {
return x.Uuid!=nil && *x.Uuid == uid
}).Map(func(x model.ZbizThirdLogin) model.ZbizThirdLogin {
return model.ZbizThirdLogin{
ID: x.ID,
ThirdName: x.ThirdName,
ThirdType: x.ThirdType,
}
}).Out()

return typed slices instead of interface{}

It would be nice if it would be possible to use methods like Map() or Filter() and get back a slice from the stream whose elements are typed like the elements in the original slice.

Actually calling .Do().Out().Val() on a mapped or filtered stream provides an empty interface.

Am I missing something or isn't it possible at the moment to retrieve typed slices from Stream?

How to get the difference between two slices

Let's suppose I need to get all elements from A that don't appear in B slice (difference), but comparing only the name.

package main

import (
	"fmt"

	"github.com/wesovilabs/koazee"
)

type product struct {
	code int
	name string
}

var fruits1 = []*product{
	{code: 9, name: "apple"},
	{code: 4, name: "orange"},
	{code: 12, name: "lemon"},
}

var fruits2 = []*product{
	{code: 1000, name: "apple"}, // The code 1000 is intentional!! I need to compare only by name
}

func main() {
	stream := koazee.StreamOf(fruits1)	
	// ??
	
	stream.ForEach(func(p *product) {
		fmt.Printf("%d: \"%s\"\n", p.code, p.name)
	}).Do()
}

Should print

4: "orange"
12: "lemon

I'm trying to figure out a good way to do that using koazee.

I think it would be great if koazee had a chunk

I want to use it like this

result := koazee.
  StreamOf([]string{"a", "b", "c"}).
  Chunk(2).
  Out().
  Val().([][]string)
// result: [][]string{{"a", "b"}, {"c"}}

result := koazee.
  StreamOf([]string{"a", "b", "c"}).
  Chunk(2).
  Map(
    func (v []string) []string {
      return append(v, "d")
    },
  ).
  Out().
  Val().([][]string)
// result: [][]string{{"a", "b", "d"}, {"c", "d"}}

GroupBy operation

GroupBy(fn func(interface{})interface{}) map[interface{}][]stream.Stream,err

For example,

myStream:= koazee.StreamOf([]Person{
    {name: "John", age: 20, male: true},
    {name: "Anna", age: 32, male: false},
    {name: "Thomas", age: 45, male: true},
    {name: "Celia", age: 17, male: false},
})
output:=myStream.GroupBy( func(p Person)bool{
   return p.age > 18
}).Do().Val()
fmt.Println(output)
// 
   {
        true: [
             {name: "John", age: 20, male: true},
             {name: "Anna", age: 32, male: false},
             {name: "Thomas", age: 45, male: true},
        ],
        false:[
             {name: "Celia", age: 17, male: false},
        ]
    }

Allow user functions to return an optional error

Some functions would be nice to use in Map, Reduce, and ForEach but they return not only the desired value, but a possible error. An example would be strconv.Atoi which could be used to map strings to ints but cannot currently be used because of the error value.

It would be useful to stop processing of a stream when an error occurs in the supplied function and make that error available to the user.

I have already implemented this for my own use and would be happy to share what I have. (You can see the updated code at https://github.com/flowonyx/koazee/tree/error-functions). The only thing I know I am missing is that I completely skip the dispatch method if the supplied function returns an error. I assume that the dispatch functions are generated, but I could not find any code to generate them.

I also do not know what impact this has on performance, though I suspect it should be minimal.

go-commands broken with go mod

Describe the bug
When importing koazee in a project which uses go mod, any command run exits with an error.

To Reproduce
Steps to reproduce the behavior:

  1. Create a dir with the following contents in main.go:
    package main
    
    import "github.com/wesovilabs/koazee"
    
    func main() {
    	t := []int{3, 2, 1}
    	n := koazee.
    		StreamOf(t).
    		Sort(func(x, y int) int {
    			if x <= y {
    				return -1
    			}
    			return 1
    		}).
    		Last().
    		Int()
    	fmt.Println(n)
    }
  2. Run go mod init
  3. Run go build or go mod why, and get the error:
    go: finding github.com/golangci/tools v0.0.0-20180902102414-2cefd77fef9b
    go: github.com/golangci/[email protected]: unknown revision 2cefd77fef9b
    go: error loading module requirements

Expected behavior
Successful command execution without error.

Screenshots

Desktop (please complete the following information):

  • OS: Linux 4.19.57-microsoft-standard (WSL2) / Windows 10 Version 1903 Build Version 18963.1000
  • Browser: -
  • Version: -

Smartphone (please complete the following information):

Additional context
There seems to be no revision 2cefd77fef9b of github.com/golangci/tools on which github.com/golangci/[email protected] depends.

Cf. ryboe/q#55

Document real scenarios

Provide articles or wiki posts where we can observer how koazee resolve real problems and the code is much readable than using simple go.

Operations with special arguments

It would be great If operations such as reduce or map could retrieve other arguments besides of the default ones, I mean

filter
func filter (item interface{}) bool
func filter (int index, item interface{}) bool
func filter (index, len int, item interface{}) bool

map
func filter (item interface{}) interface{}
func filter (int index, item interface{}) interface{}
func filter (index, len int, item interface{}) interface{}

Reduce operation should return a stream

Currently Reduce operation return a value when it's performed.

If this operation returned a stream we could do things like the below

It must be checked that after a Reduce opeartion only with can be added in the queue.

var sumElements = koazee.Stream().Reduce(func(acc, val int) int {
	return acc + val
})

func main() {
	sumElements.With([]int{1,2,3,4,5,6}).Do()
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.