Git Product home page Git Product logo

range-cmp's Introduction

range_cmp

Crates.io MIT licensed Apache licensed Build Status

Docs

This Rust crate provides the RangeComparable trait on all types that implement Ord. This traits exposes a rcmp associated method that allows comparing a value with a range of values:

use range_cmp::{RangeComparable, RangeOrdering};
assert_eq!(15.rcmp(20..30), RangeOrdering::Below);
assert_eq!(25.rcmp(20..30), RangeOrdering::Inside);
assert_eq!(35.rcmp(20..30), RangeOrdering::Above);

Empty ranges handling

This crate does not strictly handle empty ranges, which are not mathematically comparable. In this case, range_cmp will show different behavior depending on the representation of the empty range. For instance:

assert_eq!(30.range_cmp(45..35), RangeOrdering::Below);
assert_eq!(30.range_cmp(25..15), RangeOrdering::Above);
assert_eq!(0.range_cmp(0..0), RangeOrdering::Above);

range-cmp's People

Contributors

adriendellagaspera avatar qsantos avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar

range-cmp's Issues

Support values that are only `PartialOrd`

Excluding the empty range case, handling Ord values is pretty straightforward. However, implementing range comparison with only PartialOrd is non-trivial.

As a simple non-total partial order, we can use the relation “divides”. For instance, 2 divides 6 and 3 divides 6, but 4 does not divide 6. This is a partial order because:

  • reflexivity: for any natural integer (including 0) x, x divides x
  • antisymmetry: for any natural integers x and y, if x divides y and y divides x, then x = y (it follows naturally from the fact that, if x divides y, then xy)
  • transitivity: for any natural integers x, y and z, if x divides y and y divides z, then x divides z

However, this is not a total order, because 4 does not divide 6 and 6 does not divide 4.

Now, given x, y and z that implement the PartialOrd describe above, what should the relation between x and y..z be?
Note that, by definition, y..z contains all a such that verify: x divides a and a divides z. Let us consider a few cases:

  1. with 4 and 2..8 : since 2 divides 4 and 4 divides 8, the result is clearly Inside
  2. with 2 and 4..8 : since 2 divides 4, the result is clearly Below
  3. with 8 and 2..4 : since 4 divides 8, the result is clear Above
  4. with 3 and 2..8 : since 3 is not in the interval 2..8, it should not be considered Inside for this order
  5. with 3 and 4..8 : since 3 does not divide any element of 4..8, we cannot say that it is Below for this order
  6. with 9 and 2..4 : since no element of 2..4 divide 9, we cannot say that it is Above for this order

Now, the mathematical definition is valid when y divides z. But Rust's range types do not enforce this, so we have an additional case to handle:

  1. with 4 and 2..7 : 2 does not divide 7, so it is not covered by the definition

And finally, #6 applies as well:

  1. with 4 and 8..2 : the interval is empty, so comparison is meaningless

Cases 1, 2, 3 are open-and-shut. I think 4 through 8 should return None as per PartialOrd semantics. 8 is more debatable.

Fix handling of empty range

Currently, comparing a value to the empty set yields different results, depending on how it is represented:

        assert_eq!(30.range_cmp(45..35), RangeOrdering::Below);
        assert_eq!(30.range_cmp(25..15), RangeOrdering::Above);

If we want to follow the semantics of the set of values represented by the range, none of these is actually correct, and we should add a new variant for RangeOrdering for this case.

We could also decide that we want to keep this behavior, since the representations 45..35 and 25..15 actually represent different objects.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.