https://github.com/pallad-ts/range
Range structure
https://github.com/pallad-ts/range
range structures
Last synced: 14 days ago
JSON representation
Range structure
- Host: GitHub
- URL: https://github.com/pallad-ts/range
- Owner: pallad-ts
- License: mit
- Created: 2020-12-29T11:01:08.000Z (about 5 years ago)
- Default Branch: master
- Last Pushed: 2024-07-16T06:41:46.000Z (over 1 year ago)
- Last Synced: 2025-10-12T01:03:13.857Z (4 months ago)
- Topics: range, structures
- Language: TypeScript
- Homepage:
- Size: 734 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
Range 🎯
Range structure
---
[](https://circleci.com/gh/pallad-ts/range/tree/master)
[](https://badge.fury.io/js/@pallad%2Frange)
[](https://coveralls.io/github/pallad-ts/range?branch=master)
[](https://opensource.org/licenses/MIT)
---

Very simple structure with [helper methods](#helper-methods) to define range of values in following scenarios
* from A
* to A
* between A and B
# Community
Join our [discord server](https://discord.gg/G5tSBYbpej)
# Installation
```shell
npm install @pallad/range
```
# Usage
`Range` consists of 3 different interfaces
`Range.Start` that defines only a start without an end.
```typescript
interface Start {
start: T
}
```
`Range.End` that defines only an end without a start.
```typescript
interface End {
end: T;
}
```
`Range.Full` that defines both a start and an end.
```typescript
type Full = Start & End
```
The `Range` type itself is an union of all of them.
```typescript
type Range = Range.Full | Range.Start | Range.End;
```
## Creating
You can create `Range` from regular creation function, array or tuple.
Regular `create`
```typescript
// full range
Range.create(1, 100);
// start range
Range.create(1);
// end range
Range.create(undefined, 100);
```
From array or Tuple
```typescript
// start range
Range.fromArray([1])
// full range
Range.fromArray([1, 100])
// full range - other values are ignores
Range.fromArray([1, 100, 1003, 3000])
// end range
Range.fromArray([undefined, 100])
```
If creation fails, `TypeError` is thrown.
```typescript
// fails - undefined values
Range.create(undefined, null)
// fails - start greater than end
Range.create(100, 1)
// fails - empty array
Range.fromArray([])
// fails - undefined values only
Range.fromArray([undefined, null])
```
```typescript
Range.create(1, 100).value;
Range.create(null, undefined).value // 'Cannot create Range from undefined or null values'
```
## Enchanted range
Enchanted range is a range object with extra methods. Enchanted object is immutable.
```typescript
const enchantedRange = enchant(Range.create(1, 100));
enchantedRange.isWithin(40); // true
enchantedRange.isWithin(500); // false
enchantedRange.map({
start: ({start}) => `from ${start}`,
end: ({end}) => `to ${end}`,
full: ({start, end}) => `between ${start} and ${end}`
}); // 'between 1 and 100`
enchantedRange.toTuple(); // [1, 100]
```
## Checking if value is a Range
```typescript
Range.is({start: 10}) // true
Range.is({end: 10}) // true
Range.is({start: 1, end: 10}) // true
```
# Custom comparator
Boundaries comparison is a crucial feature of `Range` struct, therefore internally uses `@pallad/compare` for
comparison.
Sometimes it is not enough and you can provide your
own [comparison function](https://github.com/pallad-ts/compare#defining-custom-sorting-for-any-values).
```typescript
Range.create({value: 1}, {value: 100}, (a, b) => a.value - b.value); // no fail
Range.fromArray([{value: 1}, {value: 100}], (a, b) => a.value - b.value); // no fail
```
# Helper methods
## Mapping
Mapping converts range to any other value.
`Range.map` accepts object with properties named `start`, `end` and `full` where each of it might be a function or any
other value.
If property value is a function then result of that function gets returned, otherwise it takes the value.
```typescript
const range = Range.create(1, 100);
// mapping to simple values
Range.map(range, {start: 'start', end: 'end', full: 'full'}) // 'full'
// mapping functions
enchantedRange.map({
start: ({start}) => `from ${start}`,
end: ({end}) => `to ${end}`,
full: ({start, end}) => `between ${start} and ${end}`
}); // 'between 1 and 100`
```
## Check if value falls in range
`Range.isWithin` checks if given values falls in range. Internally uses `@pallad/compare` so custom comparison functions
for value objects are supported.
```typescript
Range.isWithin(Range.create(1, 100), 50) // true
Range.isWithin(Range.create(1, 100), 500) // false
```
### Exclusivity
By default `isWithin` treats every range as inclusive for both edges. You can change that behavior with second argument.
```typescript
const range = Range.create(1, 100);
// exclusivity = false
Range.isWithin(range, 100, false) // true
Range.isWithin(range, 1, false) // true
// same as above
Range.isWithin(range, 100) // true
Range.isWithin(range, 1) // true
// exclusivity = true
Range.isWithin(range, 100, true) // false
Range.isWithin(range, 1, true) // false
// start exclusive
Range.isWithin(range, 100, {start: true}) // true
Range.isWithin(range, 1, {start: true}) // false
// end exclusive
Range.isWithin(range, 100, {end: true}) // false
Range.isWithin(range, 1, {end: true}) // true
```
## Converting a range of a type to another range
```typescript
Range.convert(Range.create(1, 100), (value) => value + 's'); // Range { start: '1s', end: '100s' }
Range.convert(Range.create(1), (value) => value + 's'); // Range { start: '1s'}
Range.convert(Range.create(undefined, q00), (value) => value + 's'); // Range { end: '100s'}
```
Sometimes you need to map to values that cannot be easily compared, therefore you need to provide custom comparison
function to ensure proper creation of new range
```typescript
const range = Range.create(2, 100);
// custom comparison function is needed since '2s' > '100s' using regular string comparison
Range.convert(range, (value) => value + 's', (a, b) => parseInt(a) - parseInt(b));
```