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

[Feature 🔨]: Add Uniq and UniqF functions to generate only unique values #146

Open
apatniv opened this issue Oct 20, 2024 · 6 comments
Open
Labels
enhancement New feature or request

Comments

@apatniv
Copy link

apatniv commented Oct 20, 2024

Is your feature request related to a problem? Please describe.

Not really. There is workarounds possible but useful to do this in the library.

A clear and concise description of what the problem is. Ex. I'm always
frustrated when [...].

Add Uniq and UniqF functions to generate only unique values

Describe the solution you'd like

Signatures of the function:

func Uniq[V comparable](seq iter.Seq[V]) iter.Seq[V] {
	
}

func UniqF[V any](seq iter.Seq[V], comparator func(v1, v2 V) int) iter.Seq[V] {

}

Does this incur a breaking change?

No.

Do you intend to build this feature yourself?

Yes

@apatniv apatniv added the enhancement New feature or request label Oct 20, 2024
@BooleanCat
Copy link
Owner

Thanks for idea! I like the feature but would prefer different names. The functions should be "verbs" because they do something to other iterators - I'd also prefer to avoid abbreviations in function names. Perhaps FilterUnique and FilterUniqueBy or even ExcludeDuplicates might be better. Do you have other ideas?

I'm guessing you'd implement this by storing the elements you find in a map as you go along, so it would be worth mentioning in the docs that order will not be preserved if that's the route you take.

@apatniv
Copy link
Author

apatniv commented Oct 22, 2024

Makes sense I would prefer FilterUnique and FilterUniqueBy.

For FilterUnique, can't we maintain the order by looking for the current element in map and it doesn't exist, add it and yield the item.

For FilterUniqueBy, may be change the signature so that clients provide a key that can be used for hashing. This way order can be maintained.

Like

func FilterUniqueBy[V any, K comparable](seq iter.Seq[V],  key func(value V) K) iter.Seq[V] {

}

@BooleanCat
Copy link
Owner

Ah that makes sense, keep the map referenced by the closure! Can you provide an example of how you'd use FilterUniqueBy?

As for the signatures, it's fine to return iter.Seq but the argument iterators should be func(func(V) bool) so that Go's type system allows any type alias of iter.Seq to be passed without casting.

@apatniv
Copy link
Author

apatniv commented Oct 26, 2024

As for the signatures, it's fine to return iter.Seq but the argument iterators should be func(func(V) bool) so that Go's type system allows any type alias of iter.Seq to be passed without casting.

Ok. makes sense.

@apatniv
Copy link
Author

apatniv commented Oct 26, 2024

Example:

type student struct {
    id    int
    class string
}
membership := []student{
    {id: 1, class: "CS"},
    {id: 1, class: "Math"},
    {id: 100, class: "Math"},
}
uniqueStudents := FilterUniqueBy(slices.Values(membership), func(st student) int {
    return st.id
})
fmt.Printf("unique studuents:%+v\n", slices.Collect(uniqueStudents))

Prints

unique studuents:[{id:1 class:CS} {id:100 class:Math}]

@BooleanCat
Copy link
Owner

Thanks @apatniv! I'd be happy to accept a pull request for FilterUnique for the time being. As for FilterUniqueBy, I'll do some reading of other similar functions in other languages and perhaps accept a second pull request afterwards. I'll update here in comments after I've done a bit of research.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants