its-it v0.3.1
Tools for working with iterators, collections, and data.
The its-it project is a collection of utility functions intended to make it easier to work with data in JavaScript. Its design is loosely modeled on ideas from the Swift collections API and it follows the function-oriented design of date-fns
.
API
All functionality provided by its-it comes in the form of functions which are broken down into small submodules. This structure is intended to keep the project lean and make it highly compatible with tree shaking.
The iterators created by its-it are all lazy. They do no work until they are used in a for...of
loop or converted into a collection like an Array
.
Generator Iterators
These iterators generate a sequence of values based on their input parameters. They're useful for when you need some data as a starting point and can't conveniently write a C-style for-loop.
fill
An iterator whose items are provided by a function which receives an offset and the previously generated item.
import { fill } from 'its-it/fill';
const squares = fill(8, (offset, prev) => Math.pow(offset, 2));
// => 0, 1, 4, 9, 16, 25, 36, 49
maybe
An iterator whose only item is a non-null, defined value.
import { maybe } from 'its-it/fill';
const hello = maybe("hello");
// => "hello"
When passed a null or undefined value, the iterator has no items.
import { maybe } from 'its-it/fill';
const nothing = maybe();
// =>
Useful when combined with flatMap
.
range
An iterator whose items are a sequence of numbers in a specified exclusive range.
import { range } from 'its-it/range';
const numbers = range(0, 10);
// => 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
const tens = range(0, 100, 10);
// => 0, 10, 20, 30, 40, 50, 60, 70, 80, 90
A more modern feeling away to build indexing for loops.
import { range } from 'its-it/range';
for (const n of range(0, 10)) {
console.log(n);
}
repeat
An iterator which repeats a given value the specified number of times.
import { repeat } from 'its-it/repeat';
const emptyStrings = repeat(10, '');
// => '', '', '', '', '', '', '', '', '', ''
Handy for populating arrays in a certain shape.
import { repeat } from 'its-it/repeat';
const zeros = [...repeat(10, 0)];
Transforming Iterators
filter
An iterator whose items are the items of another iterator that pass a test.
import { filter } from 'its-it/filter';
const numbers = [1, 2, 3, 4, 5, 6];
const evenNumbers = filter(numbers, n => (n % 2) === 0);
// => 2, 4, 6
flatMap
An iterator whose items are the items of another iterator that have been transformed by a mapping function which returns another nested iterator.
import { flatMap } from 'its-it/flat-map';
const numbers = [1, 2, 3, 4];
const pairs = flatMap(numbers, (n) => [n, String(n)]);
// => 1, '1', 2, '2', 3, '3'
Handy for combining filter
and map
operations into a single mapping function.
import { flatMap } from 'its-it/flat-map';
import { maybe } from 'its-it/maybe';
import { range } from 'its-it/range';
const numbers = range(0, 9);
const oddNumberStrings = flatMap(numbers, (n) => {
if ((n % 2) !== 0) {
return maybe(String(n));
} else {
return maybe(null);
}
});
// => '1', '3', '5', '7', '9'
map
An iterator whose items are the items of another iterator that have been transformed by a mapping function.
import { map } from 'its-it/map';
const conditions = ['true', 'false'];
const bools = map(conditions, s => Boolean(s));
Iterator Tests
every
Check whether every item from an iterator passes a test.
import { every } from 'its-it/every';
const ages = [13, 19, 57, 39];
const copaCompliant = every(ages, age => age >= 13);
some
Check whether at least one item from an passes a test.
import { some } from 'its-it/some';
const ages = [13, 19, 57, 39];
const isAdultInTheRoom = some(ages, age => age >= 18);
Utility Functions
arraySegmentBy
Split an array into groups containing the specified number of items.
import { arraySegmentBy } from 'its-it/segment';
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9];
const segments = arraySegmentBy(numbers, 3);
// => [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
cast
Check that a value has a specified type at runtime returning undefined
if it does not.
Specify a primitive type by passing its typeof
name as the type.
import { cast } from 'its-it/cast';
function getName(json: object | undefined) {
return cast(json?.age, 'string');
}
Specify a class/constructor function by passing it as the type.
import { cast } from 'its-it/cast';
function getComments(json: object | undefined) {
return cast(json?.comments, Array);
}
Combine with unwrap
to easily write JSON parsing code.
import { cast } from 'its-it/cast';
function hydratePerson(json: unknown) {
const data = unwrap(cast(json, 'object'), 'json');
const name = unwrap(cast(data.name, 'string'), 'data.name');
const age = unwrap(cast(data.age, 'number'), 'data.age');
const comments = unwrap(cast(data.age, Array), 'data.comments');
return { name, age, comments };
}
ifNotUndef
Apply a mapping function to a value if it is not null
and not undefined
, returning undefined
otherwise.
import { ifNotUndef } from 'its-it/nullable';
const number = Math.random() > 0.5 ? Math.random() : null;
const numberString = ifNotUndef(possiblyNumber, n => new Intl.NumberFormat().format(n));
// => e.g. "54" or undefined
Very handy for JSX props.
<li>
<b>Age:</b> {ifNotUndef(data?.age, age => new Intl.NumberFormat().format(age)) ?? '--'}
</li>
isEmpty
Check whether a value is an empty string, array, map, or set.
import { isEmpty } from 'its-it/empty';
isEmpth('');
// => true
isEmpty([]);
// => true
isEmpty(new Map());
// => true
isEmpth(new Set());
// => true
onlyOne
Extract the only item of an array-like collection, throwing a RangeError
if there are no items or more than one item.
import { onlyOne } from 'its-it/only-one';
onlyOne([42]);
// => 42
onlyOne([]);
// => throw RangeError
onlyOne([99, 4]);
// => throw RangeError
unwrap
Assert that a value is not null
and not undefined
.
import { unwrap } from 'its-it/nullable';
unwrap(42);
// => 42
unwrap(undefined);
// => throw RangeError
unwrap(null);
// => throw RangeError
Provide an optional name to get a more descriptive error message.
import { unwrap } from 'its-it/nullable';
const name = unwrap(data?.name, 'data.name');