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
What do you think about Enumerator? #8
Comments
Enumerator similar to C++ STL iterators, Ruby's Enumerator and Java's Enumeration classes that allows for internal and external iteration? I wanted to do that from the start, but never found the time for it. I think that's a great addition and allows for writing more optimized code! Let me first do some research on how other languages had implemented it, because this would require a large change and only ordered collection can support this feature. |
great work |
There are a few ways of implementing this. I'd exclude the channels approach (inc. buffered channels) for performance reasons (albeit the channels have gotten faster) and (mis/over)use thereof. People seem to open a channel nowadays to add two numbers together and it feels like going after a fly with a bazooka just because bazookas are cool. Also I am uneasy about the performance of the closurer approach . So that leaves me with two patterns:
Despite being inclined towards Ruby's readability (dreaming of each/map/select/etc.), I will run some tests on both approaches this weekend and see which one works and looks better. Thanks for pointing this out, it will be great addition to this project 👍 |
I started working on enumerables and would appreciate your opinion if you would use this: import "github.com/emirpasic/gods/lists/arraylist"
func main() {
list := arraylist.New()
list.Add("a", "b", "c")
list.Each(func(index interface{}, value interface{}) {
fmt.Println(value)
})
fmt.Println(list.Map(func(index interface{}, value interface{}) interface{} {
return value
}))
fmt.Println(list.Select(func(index interface{}, value interface{}) bool {
return value.(string) >= "a" && value.(string) <= "b"
}))
fmt.Println(list.Any(func(index interface{}, value interface{}) bool {
return value.(string) == "c"
}))
fmt.Println(list.All(func(index interface{}, value interface{}) bool {
return value.(string) >= "a" && value.(string) <= "c"
}))
fmt.Println(list.Find(func(index interface{}, value interface{}) bool {
return value.(string) == "c"
}))
} Currently the enumrable interface supports the following: package enumerable
import "github.com/emirpasic/gods/containers"
type Interface interface {
// Calls the given function once for each element, passing that element's index(key) and value.
Each(func(index interface{}, value interface{}))
// Invokes the given function once for each element and returns a
// container containing the values returned by the given function.
Map(func(index interface{}, value interface{}) interface{}) containers.Interface
// Returns a new container containing all elements for which the given function returns a true value.
Select(func(index interface{}, value interface{}) bool) containers.Interface
// Passes each element of the collection to the given function and
// returns true if the function ever returns true for any element.
Any(func(index interface{}, value interface{}) bool) bool
// Passes each element of the collection to the given function and
// returns true if the function returns true for all elements.
All(func(index interface{}, value interface{}) bool) bool
// Passes each element of the collection to the given function and returns
// the first for which the function is true or nil,nil otherwise if no element
// matches the criteria.
Find(func(index interface{}, value interface{}) bool) (index interface{}, value interface{})
} Current implementation is on |
I think it's ok. |
Good point and I hope you won't need channels for this. it := list.Iterator()
for it.Next() {
value := it.Value()
...
} Does this work for you? For multiple lists it goes the same: it1 := list1.Iterator()
it2 := list2.Iterator()
for it1.Next() && it2.Next() {
value1 := it1.Value()
value2 := it1.Value()
...
} I think that's the cleanest pattern for god's containers, since there is no operator overloading. |
I think it's very good! |
Can add insert func with iter? |
Insert func is already on master, thus I closed that issue: Did you mean the above or the possibility to insert values into list during iteration (which would be hard)? |
This is almost done, PR is up, but need to update with examples and documentatio. Then I will merge it, for now you can checkout #12 if that's OK with you. Thanks again for giving me inspiration to do this :) |
thanks a lot for your work:) |
Is there reverse Iterator? |
No, not yet, but it would be good to have, especially for some data structures where that is natural. For singly linked list that wouldn't be feasible, but for doubly linked list it would make absolute sense. Can you open a new issue for reverse iterators please, because I am merging the PR that closes this issue. I'll tackle the reverse iterators in another issue + PR. |
What do you think about Enumerator?
In offical library, there is "container/list", it contains Element, that can take values one by one.
I think it takes less complex then every time find it.
The text was updated successfully, but these errors were encountered: