Preface
This article is mainly about making a record, I hope it will be useful to you
First of all, you may have seen similar JAVA codes as follows:
return (list).flatMap(list -> () .filter(Objects::nonNull) .filter(i -> (())) .map(this::mathod) .findFirst()) .orElse(null);
With limited time, we try to simulate some methods today and feel it.
gather
First we need a collection as follows:
var okgoarch = List{ "arm", "arm64", "loong64", "mips64", "mips64le", "ppc64", "riscv64", "sparc64", }
Filtering method
Next we need to try to write a filtering method. This method should accept a method, and the type that needs to be accepted by this method should be a generic type, the return value is BOOL, and then we operate on each element of the set, so the rough look is:
func (ls List) Filter(fk Predicate[string]) List { if fk == nil { return nil } var res List for _, nod := range ls { if fk(nod) { res = append(res, nod) } } return res } type Predicate[P any] func(n P) bool
Maybe some careful friends have discovered itList I defined this class myself, what if it was another type? Read down
type List []string
Define an interface to handle common types
LIST is actually similar to what I define. For the sake of convenience, there is a question here. If I define other types, it will not work. So we need to define an interface to handle the general types, so the interface comes out:
type Stream[T any] interface { Filter(pre Predicate[T]) bool }
But there is another problem. What should I do if the method implemented by other types may return not BOOL? Then the interface will grow like this. Although it is unlikely that I am still willing to do this in order to achieve the expansion, as follows:
type Stream[T, OUT any] interface { Filter(pre Predicate[T]) OUT }
Test the logic of filtering string slices
Here, a simple logic of filtering string slices is completed. Let's test it:
var okgoarch = List{ "arm", "arm64", "loong64", "mips64", "mips64le", "ppc64", "riscv64", "sparc64", } lss := okgoarch. Filter(func(n string) bool { return n == "sparc64" || n == "mips64le" }) ("%+v\n", lss) //[mips64le sparc64]
It seems to be quite successful, so I will try to implement a slightly more complicated method.
(()->{}) and other operations
Define a method structure
it is knownMAPThe flow operation method needs to accept a method type as an entry parameter. GO functional programming solves this problem well. First, we need to define a method structure, which is roughly like this:
type Function[F any, OUT any] func(n F) OUT
Define the method hereInput and outgoing ginsengThey are all generic types. I think that MAP operation is to perform a method operation on each element of the collection, so its method may look like this:
func (ls List) Map(fk Function[string, string]) List { if fk == nil { return nil } var res List for _, nod := range ls { res = append(res, fk(nod)) } return res }
Complete interface
Similarly, if it is a general type, an interface needs to be supported, otherwise slices can be used with MAP, but other types cannot. Therefore, we add a definition of the interface, and the complete interface is as follows:
type Stream[T, F2, OUT any] interface {</code><code> Filter(pre Predicate[T]) OUT</code><code> Map(function Function[T, F2]) OUT</code><code>}
Following the same method above, I defined the Sorted method and the String Joins method, as follows:
type Stream[T, F2, OUT any] interface { Filter(pre Predicate[T]) OUT Map(function Function[T, F2]) OUT }
Also, you need to add an interface, and the sorting of string slices is relatively simple. Here the method of string slicing is defined
Test it
ls := okgoarch. Filter(func(n string) bool { return n == "sparc64" || n == "mips64le" }). Map(). Sorted(). //Sort by ascii code table joins(":") ("%+v\n", [arm arm64 loong64 mips64 mips64le ppc64 riscv64 sparc64] ls)
String slices are OK, are there any other type possible
I tried to use a structure slice to illustrate the same idea and I directly posted the code:
type Person struct { Name string Age int } type ByAgeNameCompare []Person func (a ByAgeNameCompare) Len() int { return len(a) } func (a ByAgeNameCompare) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (a ByAgeNameCompare) Less(i, j int) bool { if a[i].Age == a[j].Age { return a[i].Name < a[j].Name //DESC } return a[i].Age < a[j].Age //ASC } type Persons []Person func (ls Persons) Sorted() Persons { (ByAgeNameCompare(ls)) return ls } func (ls Persons) Filter(fk Predicate[Person]) Persons { if fk == nil { return nil } var res Persons for _, nod := range ls { if fk(nod) { res = append(res, nod) } } return res } func (ls Persons) Map(fk Function[Person, any]) any { if fk == nil { return nil } var res []any for _, nod := range ls { res = append(res, fk(nod)) } return res } func (ls Persons) Map1(fk Function[Person, Person]) Persons { if fk == nil { return nil } var res Persons for _, nod := range ls { res = append(res, fk(nod)) } return res }
The above code is an implementation of the structure slice type. The structure type can be defined by itself, for example, the implementation of the stream stream interface of a certain subtype of JAVA
Complete code
type Predicate[P any] func(n P) bool type Function[F any, OUT any] func(n F) OUT type List []string type Stream[T, F2, OUT any] interface { Filter(pre Predicate[T]) OUT Map(function Function[T, F2]) OUT Sorted() OUT } func (ls List) Filter(fk Predicate[string]) List { if fk == nil { return nil } var res List for _, nod := range ls { if fk(nod) { res = append(res, nod) } } return res } func (ls List) Map(fk Function[string, string]) List { if fk == nil { return nil } var res List for _, nod := range ls { res = append(res, fk(nod)) } return res } func (ls List) joins(delim string) string { return (ls, delim) } func (ls List) Sorted() List { (ls) return ls } type Person struct { Name string Age int } type ByAgeNameCompare []Person func (a ByAgeNameCompare) Len() int { return len(a) } func (a ByAgeNameCompare) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (a ByAgeNameCompare) Less(i, j int) bool { if a[i].Age == a[j].Age { return a[i].Name < a[j].Name //DESC } return a[i].Age < a[j].Age //ASC } type Persons []Person func (ls Persons) Sorted() Persons { (ByAgeNameCompare(ls)) return ls } func (ls Persons) Filter(fk Predicate[Person]) Persons { if fk == nil { return nil } var res Persons for _, nod := range ls { if fk(nod) { res = append(res, nod) } } return res } func (ls Persons) Map(fk Function[Person, any]) any { if fk == nil { return nil } var res []any for _, nod := range ls { res = append(res, fk(nod)) } return res } func (ls Persons) Map1(fk Function[Person, Person]) Persons { if fk == nil { return nil } var res Persons for _, nod := range ls { res = append(res, fk(nod)) } return res } func main() { var okgoarch = List{ "arm", "arm64", "loong64", "mips64", "mips64le", "ppc64", "riscv64", "sparc64", } lss := okgoarch. Filter(func(n string) bool { return n == "sparc64" || n == "mips64le" }) ("%+v\n", lss) ("%+v\n", okgoarch) ls := okgoarch. Filter(func(n string) bool { return n == "sparc64" || n == "mips64le" }). Map(). Sorted(). //Sort by ascii code table joins(":") ("%+v\n", ls) peoples := Persons{ {"Alice", 30}, {"Bob", 25}, {"Charlie", 35}, {"Dark", 75}, } psvar := peoples. Filter(func(n Person) bool { return != "Charlie" }). Map(func(n Person) any { return }) ("%+v\n", psvar) psvar1 := peoples. Filter(func(n Person) bool { return != "Charlie" }). Map1(func(n Person) Person { = + "pick" return n }).Sorted() ("%+v", psvar1) } [mips64le sparc64] [arm arm64 loong64 mips64 mips64le ppc64 riscv64 sparc64] MIPS64LE:SPARC64 [Alice Bob Dark] [{Name:Bobpick Age:25} {Name:Alicepick Age:30} {Name:Darkpick Age:75}]
The above is the detailed content of the example of how GO simulates streaming operations. For more information about GO simulates streaming operations, please pay attention to my other related articles!