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

Big ranges update #74

Merged
merged 16 commits into from
May 3, 2020
Merged

Big ranges update #74

merged 16 commits into from
May 3, 2020

Conversation

passsy
Copy link
Collaborator

@passsy passsy commented Apr 25, 2020

Drastically improves the handling of ranges (1.rangeTo(10)) and expands support from int ranges to other types. Now ranges between int, double and Comparable (i.e. DateTime or String) are possible.

This PR builds upon work in #45

Progressions

Further I made a distinction between ranges and progressions.

Range

A Range (ComparableRange, IntRange, DoubleRange) describes two values (start and endInclusive) which allows checking if a third value is within that range (Range.contains(other)).

Progression

A Progression is a range which allows iterating over its values (Iterable). An IntRange extends IntProgression and allows iterating over the values with a stepSize (default 1).

When a Range doesn't extend Progression it's not possible to iterate over the values.

Difference to Kotlins ranges

The major difference between ranges in Kotlin and dartx is that our progression don't require a different function when the starting value is bigger than the end value.

//kotlin
0..10 // range from 0 to 10
10..0 // empty range from 10 to 10
10 downTo 0 // range from 0 to 10
// dartx
0.rangeTo(10) // range from 0 to 10
10.rangeTo(0) // range from 10 to 0

This also has consequences on the isEmpty property of a progression (which implements Iterable). dartx progressions are never empty, they always contain the start and end value (which might be the same).

API changes

IntRange

int.rangeTo(int end): IntRange (unchanged)

  • extends IntProgression (new)
  • isEmpty now always returns false
  • toList() returns a list containing at least start and end value.

New: DoubleRange

double.rangeTo(double end): DoubleRange

New: ComparableRange<T>

Comparable<T>.rangeTo(Comparable<T> end): ComparableRange

Commonly used for DateTime and String

Convenience extensions:

Reverse to Range.contains on can ask the value if it is between two values or within a Range.

between

  • num.between(num first, num endInclusive): bool
  • Comparable<T>.between(T first, T endInclusive): bool

inRange

  • Comparable<T>.inRange(ComparableRange<T> range): bool
  • num.inRange(Range<num> range): bool

Code samples

// test data
final killerQueen = DateTime(1974, 10, 21);
final bohemianRhapsody = DateTime(1975, 10, 31);
final underPressure = DateTime(1981, 10, 26);
final theShowMustGoOn_US_Release = DateTime(1992, 02, 06);
final freddieMercuryLifeSpan = DateTime(1946, 09, 5).rangeTo(DateTime(1991, 11, 24));
final vietnamWar = DateTime(1955, 11, 1).rangeTo(DateTime(1975, 04, 30));
// ComparableRange.contains
print(freddieMercuryLifeSpan.contains(bohemianRhapsody)); // true
print(freddieMercuryLifeSpan.contains(theShowMustGoOn_US_Release)); // false
// Comparable.between
print(bohemianRhapsody.between(killerQueen, underPressure)); // true
print(bohemianRhapsody.between(underPressure, killerQueen)); // true
print(theShowMustGoOn_US_Release.between(bohemianRhapsody, underPressure)); // false
// Comparable.inRange
print(killerQueen.inRange(freddieMercuryLifeSpan)); // true
print(bohemianRhapsody.inRange(vietnamWar)); // false
// IntRange
5.rangeTo(10).forEach(print); // 5, 6, 7, 8, 9, 10
(5.rangeTo(10)).contains(8); // true, lies between start and endInclusive
(5.rangeTo(10)).contains(11); // false
(5.rangeTo(10)).contains(7.5); // true, doubles are possible
// IntProgression
5.rangeTo(10).step(2).forEach(print); // 5, 7, 9
5.rangeTo(10).step(2).contains(7); // true
5.rangeTo(10).step(2).contains(6); // false, not a value from progression
// 5.rangeTo(10).step(2).contains(4.4); // doesn't accept doubles!

@passsy passsy requested a review from simc April 26, 2020 00:20
@passsy passsy merged commit 9064689 into master May 3, 2020
@passsy passsy deleted the feature/comparable_range_to branch May 3, 2020 17:33
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.

2 participants