Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Discussion on how to use #139

Open
wayddmldbzz opened this issue Oct 9, 2023 · 1 comment
Open

Discussion on how to use #139

wayddmldbzz opened this issue Oct 9, 2023 · 1 comment
Assignees

Comments

@wayddmldbzz
Copy link

wayddmldbzz commented Oct 9, 2023

1、First I have a struct

type KVBase struct {
	Index      int64  `json:"index"`
	Enable     bool   `json:"enable"`
	Key        string `json:"key"`
	Value      string `json:"value"`
}

2、If I have an array of this struct, I hope to do some processing on it and get a map, I can write like this

        var kvs []KVBase
	m := make(map[string]string)
	sort.Slice(kvs, func(i, j int) bool {
		return kvs[i].Index < kvs[j].Index
	})
	for _, kv := range kvs {
		if !kv.Enable {
			continue
		}
		m[kv.Key] = kv.Value
	}

3、If the same structure is put into java, I can write it like this, and the efficiency should be similar to the above, I think it's elegant

        @Data
        class KVBase {
            private int index;
            private String key;
            private String value;
            private boolean enable;
        }

        KVBase[] kvs = {};
        Map<String, String> m = Stream.of(kvs)
                                      .sorted(Comparator.comparing(kv -> kv.index < kv.index))
                                      .filter(kv -> !kv.enable)
                                      .map(kv -> Pair.of(kv.key, kv.value))
                                      .collect(Collectors.toMap(Pair::getKey, Pair::getValue));

4、I personally thought this was elegant so I was looking to see if there was something like this in Go, until I discovered this framework. I looked at the examples and found that the methods in them were not only very similar, so I tried to write them in Java.But unfortunately I just got the following code

        sort.Slice(headers, func(i, j int) bool {
		return headers[i].Index < headers[j].Index
	})
        stream_1 := stream.FromSlice(headers)
	stream_1 = stream.Filter(stream_1, func(h header) bool {
		if h.Enable {
			return true
		}
		return false
	})
	stream_2 := stream.Map(stream_1, func(h header) fun.Pair[string, string] {
		f := fun.Pair[string, string]{
			V1: h.Key,
			V2: h.Value,
		}
		return f
	})
	m := make(map[string]string)
	stream.Collect(stream_2, func(f fun.Pair[string, string]) error {
		m[f.V1] = f.V2
		return nil
	})

So I want to ask:

  1. Is this framework capable of doing the same as java? If so, could you please provide examples or where they appear?
  2. If not, is there a serious mistake in my writing method? How can I write it so that it can be almost as efficient as the first writing method? Please give an example.
@wayddmldbzz wayddmldbzz changed the title Some advice on how to use it Discussion on how to use Oct 9, 2023
@Primetalk
Copy link
Owner

Hey, @wayddmldbzz,
Thank you for your interest in this framework. Your stream-based Java-example looks nice.
The Java DSL uses an important language feature. Stream interface approximately looks like this:

interface Stream<T> {
  <R> map(Function<T, R>)
  ...
}

Unfortunately, to my knowledge Go does not support this kind of interfaces.
The only similar feature that I was able to find was to use plain functions that can take generic parameters:

func Map[T, R](Stream[T], func(T)R)

Hence, the nice Java-style DSL seems to be infeasible in the current version of Go.

Your code looks almost right. In order to make it nicer, I would make a small refactoring:

func isEnabled(h KVBase) bool {
  return h.Enabled
}

func toKeyValuePair(h KVBase) fun.Pair[string, string] {
  return fun.NewPair(h.Key, h.Value)
}

func Foo() {
        sort.Slice(headers, func(i, j int) bool {
		return headers[i].Index < headers[j].Index
	})
        headersStream := stream.FromSlice(headers)
	enabled := stream.Filter(headersStream, isEnabled)
	keyValues := stream.Map(enabled, toKeyValuePair)
	m := make(map[string]string)
	preserveKeyValue := func(f fun.Pair[string, string]) {
		m[f.V1] = f.V2
	}
	delayedStreamExecution := stream.ForEach(keyValues, preserveKeyValue)
        _, err := io.UnsafeRunSync(delayedStreamExecution)
       ...
}

Note that stream is lazy and needs UnsafeRunSync at the end.

@Primetalk Primetalk self-assigned this Oct 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants