dranges v0.2.4
Overview
This is a library that aims to implement classes that mimic ranges from D.
Why does NodeList
have to use .forEach
? Why do only arrays get for...of
support? Why do select options have to use a for(let i = 0;...)
loop?
Why can't there just be a single interface where all of these annoying, yet useful types have the same capabilities, functions, and syntax?
This is where this library comes in, as not only does it aim to provide D-like ranges, it also aims to provide an easy way to wrap common JS types into a range, allowing a mostly painless way to iterate through these data structures.
Unfortunately this is mostly for reading data from these structures, not for modifying them. For now at least.
P.S. I won't get angry and delete it this time...
Installation
Browser
Either download the source locally, or use something like unpkg to easily refer to it in a browser.
The code is an ES6 module, so can be used like so:
<script type="module">
import { drange, InputRange } from "/public/libs/dranges/dist/dranges.min.js"
// OR, if you're using unpkg or something.
import { drange, InputRange } from "https://unpkg.com/dranges@0.2.1/dist/dranges.min.js"
// I think "https://unpkg.com/dranges@0.2.1" also points to the same file.
</script>
Although it'd probably be easier to make your own "index.js" file:
// index.js
export * from "PATH_OR_URL_TO_DRANGES"
Then:
<script type="module">
import { drange } from "/public/index.js"
</script>
Which gives you better control of things.
Other
When I can be bothered, I need to distribute the code with the different module types. But for now you pretty much just do the above for any environment that supports ES6 modules.
Usage
The main usage of this library is to create InputRanges (via drange
or your own custom ways) then chain together
functions (map
, filter
, etc.) to perform a chain of algorithms to perform to provide a final output.
The public facing parts of the code are fully documented, so I advise you to take a look at it for a more concrete description of things.
Wrapping basic types into an InputRange
The following types are currently supported by the drange
function:
- NodeList
- Array
NOTE: I don't think the drange function will work for any js/ts environment that isn't the browser, as
you'll probably get a 'NodeList is not defined' kind of error. In cases like this you'll have to manually
create the wrapping ranges (e.g. new InputRangeArrayWrapper([1, 2, 3, 4])
)
import { drange, InputRange } from "/libs/dranges.min.js"
let elem = document.getElementById("tableBody");
let range = drange(elem.childNodes);
for(let e of range.map(...).filter(...))
// Do stuff
Map each value to another value lazily
import { drange, InputRange } from "/libs/dranges.min.js"
let range = drange([1, 2, 3, 4, 5]);
let sum = 0;
for(let value of range.map(num => num * 2))
sum += value;
alert(sum); // 30
Filter values based on some kind of criteria
import { drange, InputRange } from "/libs/dranges.min.js"
let range = drange([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
for(let value of range.filter(num => num % 2 == 0))
console.log(value); // 2, 4, 6, 8, 10
Check if any values meet a criteria
import { drange, InputRange } from "/libs/dranges.min.js"
let range = drange([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
console.log(range.any(n => n == 5)); // true
console.log(range.any(n => n == 15)); // false
Check if every value meets a criteria
import { drange, InputRange } from "/libs/dranges.min.js"
let range = drange([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
console.log(range.all(n => n < 11)); // true
console.log(range.all(n => n % 2 == 0)); // false
Reduce the range into a single value
import { drange, InputRange } from "/libs/dranges.min.js"
let range = drange([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
let sum = range.reduce(0, (seed, number) => seed + number);
console.log(sum); // 55
sum = range.reduce(100, (seed, number) => seed + number);
console.log(sum); // 155
Chain custom functions using 'then' and 'thenSingle'
import { drange, InputRange } from "/libs/dranges.min.js"
function squareRange(range: InputRange<number>): InputRange<number> {
return range.map(n => n * n);
}
let range = drange([1, 2, 3, 4, 5);
for(let num of range.map(n => n * 2).then(squareRange))
console.log(num); // 4, 16, 36, 64, 100
// Custom 'any' implementation using 'thenSingle'
function customAny(toFind: number, range: InputRange<number>): boolean {
for(let num of range)
{
if(num == toFind)
return true;
}
return false;
}
console.log(range.thenSingle(r => customAny(5, r))); // true
Eagerly evaluate the range to determine how many items it has
import { drange, InputRange } from "/libs/dranges.min.js"
let range = drange([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
console.log(range.walkLength); // 10
console.log(range.walkLengthUpTo(5)); // 5
console.log(range.walkLengthUpTo(15)); // 10