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, 49maybe
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, 90A 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, 6flatMap
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 undefinedVery 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());
// => trueonlyOne
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 RangeErrorunwrap
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 RangeErrorProvide an optional name to get a more descriptive error message.
import { unwrap } from 'its-it/nullable';
const name = unwrap(data?.name, 'data.name');