Skip to content

Commit 24eaaf4

Browse files
committed
Improve README
1 parent 8bf0b67 commit 24eaaf4

File tree

1 file changed

+20
-24
lines changed

1 file changed

+20
-24
lines changed

README.md

+20-24
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,16 @@
66

77
A small library that parses comma-delimited integer ranges (such as `"1-3,8-10"`) and manipulates such range data. This type of data is commonly used to specify which lines to highlight or which pages to print.
88

9-
Supported operations:
9+
Key features:
1010

11-
- Addition (e.g., `1-2,6` + `3-5` → `1-6`)
12-
- Subtraction (e.g., `1-10` - `5-9` → `1-4,10`)
11+
- Addition (aka union, e.g., `1-2,6` + `3-5` → `1-6`)
12+
- Subtraction (e.g., `1-10` − `5-9` → `1-4,10`)
1313
- Inclusion check (e.g., `3,7-9` ⊂ `1-10`)
1414
- Intersection (e.g., `1-5` ∩ `2-8` → `2-5`)
1515
- Unbounded ranges (aka infinite ranges, e.g., `5-`, meaning "all integers ≥ 5")
1616
- Ranges including negative integers or zero
1717
- ES6 iterator (`for ... of`, spread operator)
18-
- Array creation ("flatten")
18+
- Array building ("flatten")
1919

2020
The range data are always _sorted and normalized_ to the smallest possible representation.
2121

@@ -56,15 +56,14 @@ const array = mr.flatten(diff); // [1, 2, 3, 4, 5, 6, 11, 12]
5656
const len = mr.length(ranges1); // 10
5757
```
5858

59-
## Creating a _normalized_ MultiIntegerRange
59+
## Creating a normalized MultiIntegerRange
6060

61-
The fundamental data structure of this package is a **normalized** array of `[min, max]` tuples, as shown below. Here, "normalized" means the range data is in the smallest possible representation and is sorted in ascending order. You can denote an unbounded (aka infinite) range using the JavaScript constant `Infinity`.
61+
The fundamental data structure of this package is a **normalized** array of `[min, max]` tuples, as shown below. Here, 'normalized' means the range data is in the smallest possible representation and is sorted in ascending order. You can denote an unbounded (aka infinite) range using the JavaScript constant `Infinity`.
6262

6363
<!-- prettier-ignore -->
6464
```ts
6565
type Range = readonly [min: number, max: number];
6666
type MultiIntegerRange = readonly Range[];
67-
type MIR = MultiIntegerRange; // short alias
6867

6968
// Examples of normalized MultiIntegerRanges
7069
[[1, 3], [5, 6], [9, 12]] // 1-3,5-6,9-12
@@ -80,7 +79,7 @@ type MIR = MultiIntegerRange; // short alias
8079
[[Infinity, Infinity]] // makes no sense
8180
```
8281

83-
Most functions take one or two **normalized** `MultiIntegerRange`s as shown above to work correctly. To produce a valid normalized `MultiIntegerRange`, you can use `normalize()`, `parse()` or `initialize()`. (You can write a normalized `MultiIntgerRange` by hand as shown above, too.)
82+
Most functions take one or two **normalized** `MultiIntegerRange`s as shown above to work correctly. To produce a valid normalized `MultiIntegerRange`, you can use `normalize()`, `parse()` or `initialize()`. You can write a normalized `MultiIntgerRange` by hand as shown above, too.
8483

8584
`normalize(data?: number | (number | Range)[])` creates a normalized `MultiIntegerRange` from a single integer or an unsorted array of integers/`Range`s. This and `initialize` are the only functions that can safely take an unsorted array. Do not pass unnormalized range data to other functions.
8685

@@ -125,7 +124,9 @@ console.log(
125124

126125
See [api-reference.md](api-reference.md).
127126

128-
## Iteration
127+
## Tips
128+
129+
### Iteration
129130

130131
Since a `MultiIntegerRange` is just an array of `Range`s, if you naively iterate over it (e.g., in a for-of loop), you'll simply get each `Range` tuple one by one. To iterate each integer contained in the `MultiIntegerRange` instead, use `iterate()` like so:
131132

@@ -145,15 +146,13 @@ const arr1 = [...mr.iterate(ranges)]; //=> [2, 5, 6, 7]
145146
const arr2 = Array.from(mr.iterate(ranges)); //=> [2, 5, 6, 7]
146147
```
147148

148-
## Tip
149-
150149
### Combine Intersection and Unbounded Ranges
151150

152151
Intersection is especially useful to "trim" unbounded ranges.
153152

154153
```ts
155154
const userInput = '-5,15-';
156-
const pagesInMyDoc = [[1, 20]]; // (1-20)
155+
const pagesInMyDoc = [[1, 20]]; // 1-20
157156
const pagesToPrint = mr.intersect(
158157
mr.parse(userInput, { parseUnbounded: true }),
159158
pagesInMyDoc
@@ -165,23 +164,17 @@ for (const page of mr.iterate(pagesToPrint)) await printPage(page);
165164

166165
For compatibility purposes, version 5 exports the `MultiRange` class and `multirange` function, which is mostly compatible with the 4.x API but has been rewritten to use the new functional API under the hood. See the [4.x documentation](https://github.com/smikitky/node-multi-integer-range/tree/v4.0.9) for the usage. The use of this compatibility layer is discouraged because it is not tree-shakable and has no performance merit. Use this only during migration. These may be removed in the future.
167166

168-
## Changelog
169-
170-
See [CHANGELOG.md](CHANGELOG.md).
171-
172167
## Caveats
173168

174-
**Performance Considerations**: This library works efficiently for large ranges
175-
as long as they're _mostly_ continuous (e.g., `1-10240000,20480000-50960000`). However, this library is not intended to be efficient with a heavily fragmented set of integers that are scarcely continuous (e.g., random 10000 integers between 1 to 1000000).
169+
**Performance Considerations**: This library works efficiently for large ranges as long as they're _mostly_ continuous (e.g., `1-10240000,20480000-50960000`). However, this library is not intended to be efficient with a heavily fragmented set of integers that are scarcely continuous (e.g., random 10000 integers between 1 to 1000000).
176170

177-
**No Integer Type Checks**: Make sure you are not passing floating-point `number`s
178-
to this library. For example, don't do `normalize(3.14)`. For performance reasons, the library does not check if a passed number is an integer. Passing a float will result in unexpected and unrecoverable behavior.
171+
**No Integer Type Checks**: Make sure you are not passing floating-point `number`s to this library. For example, don't do `normalize(3.14)`. For performance reasons, the library does not check if a passed number is an integer. Passing a float will result in unexpected and unrecoverable behavior.
179172

180173
## Comparison with Similar Libraries
181174

182-
[range-parser](https://www.npmjs.com/package/range-parser) specializes in parsing range requests in HTTP headers as defined in RFC 7233. It comes with behavior that cannot be turned off and is inappropriate for other purposes. For example, `'-5'` means "last 5 bytes".
175+
[range-parser](https://www.npmjs.com/package/range-parser) specializes in parsing range requests in HTTP headers as defined in RFC 7233, and it behaves in a way that is usually inappropriate for other purposes. For example, `'-5'` means "last 5 bytes".
183176

184-
[parse-numeric-range](https://www.npmjs.com/package/parse-numeric-range) is fine for small ranges, but it always builds a "flat" array, so it is very inefficient for large ranges such as byte ranges. Also, whether you like it or not, it handles overlapping or descending ranges as-is without normalization. For example, `'4-2,1-3'` results in `[4, 3, 2, 1, 2, 3]`.
177+
[parse-numeric-range](https://www.npmjs.com/package/parse-numeric-range) is fine for small ranges, but it always builds a "flat" array, which makes it very inefficient for large ranges such as byte ranges. Also, whether you like it or not, it handles overlapping or descending ranges as-is, without normalization. For example, `'4-2,1-3'` results in `[4, 3, 2, 1, 2, 3]`.
185178

186179
multi-integer-range is a general-purpose library for handling this type of data structure. It has a default parser that is intuitive enough for many purposes, but you can also use a custom parser. Its real value lies in its ability to treat normalized ranges as intermediate forms, allowing for a variety of mathematical operations. See the [API reference](api-reference.md).
187180

@@ -190,12 +183,11 @@ multi-integer-range is a general-purpose library for handling this type of data
190183
| '1-3' | [[1, 3]] | [{ start: 1, end: 3 }] | [1, 2, 3] |
191184
| '1-1000' | [[1, 1000]] | [{ start: 1, end: 1000 }] | [1, 2, ..., 999, 1000 ] ⚠️ |
192185
| '5-1' | [[1, 5]] | (error) | [5, 4, 3, 2, 1] |
193-
| '1-3,2-4' | [[1, 4]] | [{ start: 1, end: 4 }] <sup>1</sup> | [1, 2, 3, 2, 3, 4] |
194186
| '4-2,1-3' | [[1, 4]] | [{ start: 1, end: 3 }] ⚠️<sup>1</sup> | [4, 3, 2, 1, 2, 3] |
195187
| '-5' | [[-Infinity, 5]] <sup>2</sup> | [{ start: 9995, end: 9999 }] <sup>3</sup> | [-5] |
196188
| '5-' | [[5, Infinity]] <sup>2</sup> | [{ start: 5, end: 9999 }] <sup>3</sup> | [] |
197189

198-
<sup>1</sup>: With `combine` option. <sup>2</sup>: With `parseUnbounded` option. <sup>3</sup>: When size is 10000.
190+
<sup>1</sup>: With `combine` option. <sup>2</sup>: With `parseUnbounded` option. <sup>3</sup>: When `size` is 10000.
199191

200192
## Development
201193

@@ -215,6 +207,10 @@ npm run build
215207

216208
Please report bugs and suggestions using GitHub issues.
217209

210+
## Changelog
211+
212+
See [CHANGELOG.md](CHANGELOG.md).
213+
218214
## Author
219215

220216
Soichiro Miki (https://github.com/smikitky)

0 commit comments

Comments
 (0)