-
Notifications
You must be signed in to change notification settings - Fork 17.9k
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
proposal: strings, bytes: Add JoinSeq #70034
Comments
Related Issues and Documentation (Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.) |
Do you imagine that it would collect all the items from the sequence first to figure out the total length of the final string before concatenating them? |
I imagine it would just use a strings.Builder and opt into whatever the default buffer there is. Maybe there could be optimization to use a slice for sequences shorter than N. |
1.23+ iterators will change Go culture. But should it? |
I don't think this is a change on the scale of adding iter.Map or iter.Filter where it would materially affect the experience of using Go. This is pretty much just the same as #61901. In fact I proposed it in that issue already. |
My intuition for a function like this is that by choosing to use an iterator I'm implying that it's not important to preallocate exactly the right number of bytes for the result, and so I expect the implementation to be like using If avoiding potential intermediate allocations were important to me then I think using just an iterator would be applying the wrong tool. However, for package bytes
func AppendJoinSeq(s []byte, seq iter.Seq[string], sep string) []byte ...and then a caller that does know (or can at least make a good estimate of) the expected result length can provide some excess capacity of that size for the function to write into. Assuming a (This comment is effectively making a separate proposal, but I'm posting it here as indirect support for the proposed |
This should be a sum function for Reduce in #61898 |
another way to cut this is package iterx
func Join[T any](seq iter.Seq[T], sep T) iter.Seq[T] and package bytes
func Flatten(seq iter.Seq[[]byte]) []byte and for strings as well. |
In the case of strings at least, adding the substrings in a reduce operation is likely to be significantly less efficient than using a dedicated function that can do some smart buffering. |
You could use func Separate[T any](seq iter.Seq[T], sep T) iter.Seq[T] {
return func(yield func(T) bool) {
first := true
for v := range seq {
if !first && !yield(sep) {
return
}
first = false
if !yield(v) {
return
}
}
}
} Then it would just be Edit: I realize that I misread your comment and missed the part about optimizing the buffering of the separators. Whoops. Ah well. |
Proposal Details
#61901 added SplitSeq and friends to bytes, but nothing for joining. Right now you have to do slices.Collect first or use a bytes.Buffer/strings.Builder, which feels unfortunate. I propose to add
strings.JoinSeq(seq iter.Seq[string], sep string) string
and the bytes equivalent as well.The text was updated successfully, but these errors were encountered: