Skip to content

Add Array#to_ranges #265

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

aguynamedryan
Copy link
Contributor

I needed this code for a project and figured I'd offer it up to facets

I originally found this code at
https://dzone.com/articles/convert-ruby-array-ranges
but it didn't actually work as described, so I fixed it.

I needed this code for a project and figured I'd offer it up to facets

I originally found this code at
https://dzone.com/articles/convert-ruby-array-ranges
but it didn't actually work as described, so I fixed it.
@trans
Copy link
Member

trans commented Oct 26, 2016

Looks good to me. But the tests didn't run for some reason. I don't think it's your code. I'll look into it and get back to you.

@ioquatix
Copy link
Contributor

It's odd that travis blew up.

Can we make self.compact.uniq.sort better?

Compact is O(N). Uniq might be O(N^2) search? sort is okay.

However, it's also making 3 copies of the array for no reason. Could be even self.dup.sort!.uniq!.compact! or something like that.

@ioquatix
Copy link
Contributor

if !array.empty? AFTER you already did compact.uniq.sort seems inefficient. It could be the first line.

return self if self.empty?

@trans
Copy link
Member

trans commented Oct 26, 2016

Yes, but it should be a new array.

return [] if empty?

@ioquatix
Copy link
Contributor

ioquatix commented Oct 26, 2016

Well, it depends on the assumptions you want to make, but I prefer not doing additional allocations.

^_^ > irb
2.3.0 :001 > x = []
 => [] 
2.3.0 :002 > x.object_id
 => 70296120613840 
2.3.0 :003 > x.sort.object_id
 => 70296111721840 

As an example, sort returns a new array, so it supports your argument.

@trans
Copy link
Member

trans commented Oct 26, 2016

In fact something like:

    def to_ranges
      ranges = []
      return ranges if empty?
      array = uniq.compact
      return ranges if array.empty?
      array.sort!
      ...

And get rid of the if !array.empty? clause altogether.

@ioquatix
Copy link
Contributor

While we are on the topic of bike shedding lol, perhaps compact is unnecessary. Because it should be a contract of the caller to provide the right kind of array?

@ioquatix
Copy link
Contributor

Anyway if it can be improved with the above advice I think it's a good addition.

@trans
Copy link
Member

trans commented Oct 26, 2016

Well, it depends on the assumptions you want to make, but I prefer not doing additional allocations.

In this case you really have to because if you return self they could modify it in place,

f = [1,2,3]
g = f.to_ranges
g << (4..5)
f  => [1..3,4..5]

And that's not what would be expected.

@trans
Copy link
Member

trans commented Oct 26, 2016

While we are on the topic of bike shedding lol, perhaps compact is unnecessary. Because it should be a contract of the caller to provide the right kind of array?

I suspect that the algorithm won't do what one expects then. I have to try it, but I expect we'd get things like,

[1,2,2,3,3].to_ranges  #=> [1..2,2..2,3..3]

And I don't think that would ever be what anyone wants. That being so the compact is really an integral part of the behavior.

@aguynamedryan What do you think?

@trans
Copy link
Member

trans commented Oct 28, 2016

Hey I just rediscovered that Facets already has this, arrange. So the task now becomes to compare implementations, and improve the code accordingly. Also, I think we need to ask if the name "arrange" is really the right one. Perhaps at the very least, we could alias to_ranges -- but is it good practice to call a method "to_foo" when there is no Foo class?

@ioquatix
Copy link
Contributor

ioquatix commented Nov 7, 2016

Well, there is a Range class. to_ranges is just a plural.. so it makes sense in a way.

@ioquatix
Copy link
Contributor

ioquatix commented Nov 7, 2016

The name arrange is pretty unintuitive IMHO.

@trans
Copy link
Member

trans commented Nov 20, 2016

@ioquatix You know, you are right. I'll change it to #to_ranges and figure out the best implementation between this and the current #arrange.

Someone remind me to do this if I haven't gotten around to it within the next few weeks.

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

Successfully merging this pull request may close these issues.

3 participants