Really simple functions for working with built-in collection types, inspired by F#'s collection modules design.
- Modules for iterables, arrays, maps and sets.
- Composable functional design with full type-safety when used with TypeScript.
Add package using NPM or yarn
npm i --save collection-fns
yarn add collection-fns
You can import the top level modules directly:
import { Iterables, Arrays, Sets, Maps, pipe } from 'collection-fns'
Additionally, you can import the specific module functions from dist/lib/[module]
:
import { groupBy } from 'collection-fns/dist/lib/iterables'
Calculating primes lazily with iterators:
import { pipe } from 'collection-fns'
import { init, map, filter, count } from 'collection-fns/dist/lib/iterables';
const primes = pipe(
init({ from: 1, to: 100 }),
map(x => ({
x,
factors: pipe(
init({ from: 1, to: x }),
filter(y => x % y === 0)
)
})),
filter(num => count(num.factors) === 2),
map(num => num.x)
)
for (const prime of primes) {
console.log(prime)
}
Grouping numbers into odd and even buckets
import { pipe, Maps } from 'collection-fns'
import { init, groupBy } from 'collection-fns/dist/lib/arrays';
const oddAndEven = pipe(
init({ from: 1, to: 25 }),
groupBy(i => i % 2 === 0 ? 'even' : 'odd'),
Maps.ofArray
)
This works by use of partial application, however all functional can also be called directly such as:
Iterables.map(
Iterables.init({ from: 1, to: 10 }),
x => x * x))
The pipe()
function is a stand-in until the pipe (|>
) operator gets implemented in ESNext.
For pipes of up to 26 steps, the multi-argument overloads can be used where the first argument is the initial value, and all following arguments are functions take the result of the step before and returning a new result. The result from the final step is then returned as the result of the pipe.
For longer pipes there is an alternative syntax:
- The pipe is started by passing
pipe(...)
a single initial value. - Each
.then(...)
step in a pipe takes a callback that is passed the value from the previous step. - At the end of the pipe, access the
.result
property to get the value returned from the last step.
Taking the example from the proposal linked above:
function doubleSay (str) {
return str + ", " + str;
}
function capitalize (str) {
return str[0].toUpperCase() + str.substring(1);
}
function exclaim (str) {
return str + '!';
}
The following statements are equivalent:
let result = exclaim(capitalize(doubleSay("hello")));
result // Prints: "Hello, hello!"
let result = pipe(
"hello",
doubleSay,
capitalize,
exclaim
)
result // Prints: "Hello, hello!"
let result =
pipe("hello")
.then(doubleSay)
.then(capitalize)
.then(exclaim)
.result
result // Prints: "Hello, hello!"
yarn test
: Run test suiteyarn start
: Runyarn build
in watch modeyarn test:watch
: Run test suite in interactive watch modeyarn test:prod
: Run linting and generate coverageyarn build
: Generate bundles and typings, create docsyarn lint
: Lints codeyarn commit
: Commit using conventional commit style (husky will tell you to use it if you haven't 😉)