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

Add Range#clamp #10148

Open
straight-shoota opened this issue Dec 28, 2020 · 4 comments · May be fixed by #10300 or #15106
Open

Add Range#clamp #10148

straight-shoota opened this issue Dec 28, 2020 · 4 comments · May be fixed by #10300 or #15106

Comments

@straight-shoota
Copy link
Member

Range isn't Comparable, but it could very well define a #clamp method. The result would be the intersection of both ranges.

(-5..5).clamp(0..100)    # =>  0..5
(-5..5).clamp(-100..100) # => -5..5
(-5..5).clamp(..)        # => -5..5
(-5...5).clamp(-100...0) # => -5...0

This method could also be called #intersect or #&, but IMO #clamp fit's best because it closely resembles Comparable#clamp.

There are a few cases where the expected results may be up for discussion:

  • Mixing exclusive and inclusive ranges ((-5..5).clamp(-10...2) and (-5...5).clamp(-10..2)) should probably have the same result as if both ranges were exclusive.
  • If both ranges are disparate ((-5..5).clamp(10..100)), the result should probably be an empty range. This can be expressed as an exclusive range with identical begin and end (x...x). But what should x be? Probably best to use the begin of the clamped range (-5...-5).
  • If the direction of the ranges is different (-5..5.clamp(10..-10)), we could try to sort things out, but I suppose it's probably better to just treat them as disparate and return an empty range.
@cristian-lsdb
Copy link
Contributor

We can follow the same rules as Array#&

## inclusive ranges
(-5..5).to_a & (0..100).to_a # => [0, 1, 2, 3, 4, 5]
(-5..5).to_a & (-100..100).to_a # => [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]

## exclusive ranges
(-5...5).to_a & (-100...0).to_a # => [-5, -4, -3, -2, -1]

## exclusive and inclusive ranges
(-5..5).to_a & (-10...2).to_a # => [-5, -4, -3, -2, -1, 0, 1]
(-5...5).to_a & (-10..2).to_a # => [-5, -4, -3, -2, -1, 0, 1, 2]

Some differences:
Array don’t have an equivalent of beginless range (..).
For empty intersections, Array#& return an empty array. But for a range, I don’t know, do it make a difference if the empty range is -5...-5 or 100...100 ?
And a range with an inverted direction is an empty range (10..-10).to_a # => [] but this seems to be a bug.

@mattrberry
Copy link
Contributor

Literally just had a use-case for this and searched for it in the docs. +1 :)

@straight-shoota straight-shoota linked a pull request Jan 26, 2021 that will close this issue
@oprypin
Copy link
Member

oprypin commented Dec 2, 2024

intersection would probably supercede clamp.

@CTC97 CTC97 linked a pull request Dec 6, 2024 that will close this issue
@CTC97
Copy link
Contributor

CTC97 commented Dec 6, 2024

intersection would probably supercede clamp.

Agree - I think it makes sense to close this issue with that PR or create an alias for intersect.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants