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

Allow cls parameter of iter_all to take an iterable of classes rather than a single class #426

Open
leleogere opened this issue Feb 3, 2025 · 0 comments · May be fixed by #428
Open

Allow cls parameter of iter_all to take an iterable of classes rather than a single class #426

leleogere opened this issue Feb 3, 2025 · 0 comments · May be fixed by #428
Assignees
Labels
enhancement New feature or request

Comments

@leleogere
Copy link
Collaborator

When iterating over elements in a part, I sometimes need to iterate over multiple types of elements (e.g. GenericNote and Tuplet). However, currently, the iter_all method only allows searching for one class (eventually including subclasses).

If I want to get all GenericNote and Tuplet objects, I can currently think of two workarounds:

  • iter_all over all elements, and then filtering only for GenericNote and Tuplet objects
    • Advantage: very flexible
    • Disadvantage: very slow (as we iterate over all objects instead of just the ones we are interested in)
  • iter_all once for each cls I need and merge the two results somehow
    • Advantage: iteration faster as we only iterate over GenericNote the first time, and Tuplet the second time (rather than over all objects as before)
    • Disadvantages:
      • Still a bit slow as iterating twice over all timepoints, once for GenericNote and once for Tuplet (and it would be even slower if I would like to gather 3, 4... types of objects)
      • Needs merging the results somehow, which might not be directly straightforward with iterators, as we need to compare the start time of the elements coming for each iterator in order to have the final iterator still sorted by time

I feel like an interface like the following could be quite handy:

part.iter_all(cls=[GenericNote, Tuplet], include_subclasses=True)

This would return an iterator with all GenericNote and Tuplet object (and their subclasses). In case of simultaneous event of both types, the order would be the same as the order of classes passed to the function, i.e. in this case all GenericNote first, then all Tuplet. Note that this iterator would only iterate once over all timepoints, and only on required classes, which would make it faster than the two workaround explained above.

Note that the include_subclasses parameter (as well as other parameters) would apply to all classes. I might be possible to allow passing a list of values (of the same size as cls) specifying the parameter for each class, but I'm not sure that it would be that useful. Let me know if you think it would.

I'm going to have a go at implementing that soon. I still have one interrogation: what if the user passes cls=[GenericNote, Note] with include_subclasses=True? (or even cls=[Note, Note]) Should the Note objects be duplicated? Or should each object only appear once anyway? Or should the function raise an exception? I would be interested in hearing your thoughts about that.

@leleogere leleogere self-assigned this Feb 3, 2025
@leleogere leleogere linked a pull request Feb 5, 2025 that will close this issue
@leleogere leleogere linked a pull request Feb 5, 2025 that will close this issue
@leleogere leleogere added the enhancement New feature or request label Feb 27, 2025
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

Successfully merging a pull request may close this issue.

1 participant