Highly generic traits/interfaces.
Laws
These apply to all traits in this module.
- Arrays, Strings and any list-like data structures are treated as mappings from index -> value
- Array sparseness is ignored on read; any list-like container
hasa specific index ifsize(myContainer) => key; getting an unset value yieldsundefined - Sets are treated as mappings from a key to itself
- Source:
Interfaces
Methods
(inner) assertEquals(a, b, msg)
- Source:
- See:
-
Equals for examples
Assert that eq(actual, expected)
const { throws: assertThrows } = require('assert');
const { assertEquals } = require('ferrum');
assertEquals([{foo: 42}], [{foo: 42}]); // OK!
assertThrows(() => assertEquals([1,2,3], [1,2]));
Version history
- 1.2.0 Support for objects with Symbol keys.
Parameters:
| Name | Type | Description |
|---|---|---|
a |
A | |
b |
B | |
msg |
String | undefined | The error message to print |
Throws:
(inner) assertUneq(a, b, msg)
- Source:
- See:
-
Equals for examples
Assert that !eq(actual, expected)
const { throws: assertThrows } = require('assert');
const { assertUneq } = require('ferrum');
assertUneq(1, 2);
assertThrows(() => assertUneq([{foo: 42}], [{foo: 42}])); // AssertionError!
Version history
- 1.2.0 Support for objects with Symbol keys.
Parameters:
| Name | Type | Description |
|---|---|---|
a |
A | |
b |
B | |
msg |
String | undefined | The error message to print |
Throws:
AssertionError
(inner) assign(cont, key, value)
- Source:
Set a value in a container. Always returns the given value.
const { assign, each, assertEquals } = require('ferrum');
const o = {};
const m = new Map();
const a = [];
// Normal assignment
assign(o, 'foo', 42);
assertEquals(o, { foo: 42 });
// Assignment using currying
each([o, m, a], assign(2, 'bar'));
assertEquals(o, { foo: 42, 2: 'bar' });
assertEquals(m, new Map([[ 2, 'bar' ]]));
assertEquals(a, [undefined, undefined, 'bar']);
Version history
- 1.2.0 Support for objects with Symbol keys.
Parameters:
| Name | Type | Description |
|---|---|---|
cont |
* | The container |
key |
* | The key |
value |
* | The value to set |
(inner) deepclone(a) → {A}
- Source:
- See:
-
Deepclone for examples
Recursively clone an object
const { notStrictEqual: assertIsNot } = require('assert');
const { deepclone, assertEquals, assertUneq } = require('ferrum');
const a = {foo: []};
const b = deepclone(a);
// After cloning, the top level element is equal to the original,
// but it is a clone.
assertIsNot(a, b);
assertEquals(a, b);
// The children are also cloned, mutating them will not propagate
// to the origina
b.foo.push(42);
assertIsNot(a.foo, b.foo);
assertUneq(a.foo, b.foo);
assertEquals(a.foo, []);
assertEquals(b.foo, [42])
Version history
- 1.2.0 Support for objects with Symbol keys.
Parameters:
| Name | Type | Description |
|---|---|---|
a |
A |
Returns:
- Type
- A
(inner) del(x, k)
- Source:
Delete an entry with the given key from a container
const { del, each, assertEquals } = require('ferrum');
const o = { foo: 42, bar: '13' };
const m = new Map([[ 'foo', true ]]);
// Normal assignment
del(o, 'bar');
assertEquals(o, { foo: 42 });
// Assignment using currying
each([o, m], del('foo'));
assertEquals(o, {});
assertEquals(m, new Map());
Version history
- 1.2.0 Support for objects with Symbol keys.
Parameters:
| Name | Type | Description |
|---|---|---|
x |
* | The container to delete from |
k |
* | The key to delete |
(inner) empty(what) → {Boolean}
- Source:
- See:
-
Size for examples
Determine if a container is empty. Uses size(x) === 0a
const assert = require('assert');
const { empty, reject, assertSequenceEquals } = require('ferrum');
assert(empty([]));
assert(empty({}));
assert(!empty("asd"));
// This is also particularly useful as a predicate for sequence
// functions like filter, reject, contains, find, etc.
// Eg. the following code will remove any empty containers from a sequence
// regardless of type
const rejectEmpty = reject(empty);
assertSequenceEquals(
rejectEmpty([{foo: 23}, "", [], new Set(), "42"]),
[{foo: 23}, "42"]);
Version history
- 1.2.0 Support for objects with Symbol keys.
Parameters:
| Name | Type | Description |
|---|---|---|
what |
T |
Returns:
- Type
- Boolean
(inner) eq(a, b) → {Boolean}
- Source:
- See:
Determine whether two values are equal using the Equals trait.
const assert = require('assert');
const { eq, assertSequenceEquals, reject } = require('ferrum');
// Should give the same results as `===` for primitive values
assert(eq(true, true));
assert(eq(null, null));
assert(eq(undefined, undefined));
assert(eq("asd", "asd"));
assert(eq(Symbol.iterator, Symbol.iterator));
assert(!eq("", 0));
assert(!eq(1, 2));
// Can also compare more complex structures
assert(eq([{foo: 42}], [{foo: 42}]));
assert(!eq([{foo: 42}], [{bar: 11}]));
// This is also particularly useful as a predicate for sequence
// functions like filter, reject, contains, find, etc.
// Eg. the following code will remove any objects equal to {foo: 23}
const inp = [{foo: 42}, {foo: 23}, {foo: 23, bar: 1}];
assertSequenceEquals(
reject(inp, eq({foo: 23})),
[{foo: 42}, {foo: 23, bar: 1}]);
This function is a bit more powerful than than the Equals trait itself:
First of all it searches for a Equals implementation for both arguments
and it falls back to === if none is found.
For this reason using eq() is usually preferred over using the Equals trait directly.
Version history
- 1.2.0 Support for objects with Symbol keys.
Parameters:
| Name | Type | Description |
|---|---|---|
a |
A | |
b |
B |
Returns:
- Type
- Boolean
(inner) get(x, k) → {*}
- Source:
Given a key, get a value from a container.
Normally you would use the object[value] operator for this or
Map::get. The advantage of using this function is that it works
for any container (that implements the Trait), so it helps you
write more generic functions.
const { strictEqual: assertIs } = require('assert');
const { get, assertSequenceEquals, map } = require('ferrum');
assertIs(get({foo: 42}, 'foo'), 42);
// Get is particularly useful for more complex use cases; in this
// example for instance we extract the key `1` from a variety of containers;
const inp = [
['foo', 'bar'],
new Map([[1, 42]]),
new Set([1]),
{1: 'bang'},
];
assertSequenceEquals(
map(inp, get(1)),
['bar', 42, 1, 'bang']);
Version history
- 1.2.0 Support for objects with Symbol keys.
Parameters:
| Name | Type | Description |
|---|---|---|
x |
* | The container to get the key of. Must implement the Get trait. |
k |
* | The key to retrieve the value for |
Returns:
The value
- Type
- *
(inner) has(x, k)
- Source:
Test if a container includes an entry with the given key
const assert = require('assert');
const { has, filter, assertSequenceEquals } = require('ferrum');
assert(has({foo: 42}, 'foo'));
assert(!has({foo: 42}, 'bar'));
// Get is particularly useful with filter/reject/find/...
// This example will return all containers that have the 'value' key
const dat = [{ value: 13 }, { ford: 42 }];
assertSequenceEquals(
filter(dat, has('value')),
[{ value: 13 }]);
Version history
- 1.2.0 Support for objects with Symbol keys.
Parameters:
| Name | Type | Description |
|---|---|---|
x |
* | The container |
k |
k | The key to check |
(inner) isImmutable(v) → {Boolean}
- Source:
- See:
-
Immutable for examples
Test whether a given value is immutable.
const assert = require('assert');
const { isImmutable } = require('ferrum');
assert(isImmutable(42));
assert(isImmutable('asd'));
assert(isImmutable(Symbol()));
assert(isImmutable(null));
assert(isImmutable(undefined));
assert(isImmutable(/asd/));
assert(isImmutable(() => {}));
assert(!isImmutable({}));
assert(!isImmutable([]));
assert(!isImmutable(new Map()));
assert(!isImmutable(new Set()));
Parameters:
| Name | Type | Description |
|---|---|---|
v |
T |
Returns:
- Type
- Boolean
(generator, inner) keys(what)
- Source:
- See:
Get an iterator over the keys of a container. Uses pairs(c).
const {keys, assertSequenceEquals} = require('ferrum');
assertSequenceEquals(keys(['a', 'b']), [0, 1]);
assertSequenceEquals(keys(new Set([1, 2])), [1, 2]);
assertSequenceEquals(keys({foo: 42}), ['foo']);
Version history
- 1.2.0 Support for objects with Symbol keys.
Parameters:
| Name | Type | Description |
|---|---|---|
what |
T |
Yields:
(inner) pairs(what) → {Array}
- Source:
- See:
Get an iterator over any container.
Always returns pairs [key, value], this distinguishes pairs()
from iter()/normal iteration.
Note that usually you should use iter() over pairs unless you
really know that forcing a container into key/value representation
is needed (e.g. Array with indices) since pairs() will only work
on a very select number of containers, while iter() will work on
any iterators and will actually support lists of key value pairs.
const { pairs, assertSequenceEquals } = require('ferrum');
assertSequenceEquals(pairs("as"), [[0, "a"], [1, "s"]]);
assertSequenceEquals(pairs({foo: 42}), [['foo', 42]]);
assertSequenceEquals(pairs(['a', 'b']), [[0, 'a'], [1, 'b']]);
assertSequenceEquals(pairs(new Set([1, 2])), [[1, 1], [2, 2]]);
assertSequenceEquals(pairs(
new Map([["foo", "bar"], ["baz", "bang"]])),
[["foo", "bar"], ["baz", "bang"]]);
Version history
- 1.2.0 Support for objects with Symbol keys.
Parameters:
| Name | Type | Description |
|---|---|---|
what |
T |
Yields:
- Type
- Array
(inner) replace(x, k, v) → {*}
- Source:
Swap out one value in a container for another.
const { replace, map, assertEquals, assertSequenceEquals } = require('ferrum');
const o = { foo: 42 };
const m = new Map([[ 'bar', 'hello' ]]);
// Normal assignment
assertEquals(replace(o, 'bar', 1), undefined);
assertEquals(replace(o, 'foo', 2), 42);
assertEquals(o, { foo: 2, bar: 1});
// Assignment using currying
assertSequenceEquals(
map([o, m], replace('bar', 'world')),
[ 1, 'hello' ]);
assertEquals(o, { foo: 2, bar: 'world' });
assertEquals(m, new Map([[ 'bar', 'world' ]]));
Version history
- 1.2.0 Support for objects with Symbol keys.
Parameters:
| Name | Type | Description |
|---|---|---|
x |
* | The container to replace a value in |
k |
* | The key of the value to replace |
v |
* | The new value |
Returns:
Whatever the value was before the replace.
- Type
- *
(inner) setdefault(x, k, v) → {*}
- Source:
If the key is present in the container, return the value associated with the key. Otherwise, assign the supplied default value to the key and return that value.
const { setdefault, map, assertEquals, assertSequenceEquals } = require('ferrum');
const o = { foo: 42 };
const m = new Map();
// Normal assignment
assertEquals(setdefault(o, 'bar', 1), 1);
assertEquals(setdefault(o, 'foo', 2), 42);
assertEquals(o, { foo: 42, bar: 1});
// Assignment using currying
assertSequenceEquals(
map([o, m], setdefault('foo', 3)),
[ 42, 3 ]);
assertEquals(o, { foo: 42, bar: 1 });
assertEquals(m, new Map([[ 'foo', 3 ]]));
Version history
- 1.2.0 Support for objects with Symbol keys.
Parameters:
| Name | Type | Description |
|---|---|---|
x |
* | The container |
k |
* | The key to search for |
v |
* | The default value |
Returns:
Whatever the container now has associated with k.
- Type
- *
(inner) shallowclone(a) → {A}
- Source:
- See:
-
Shallowclone for examples
Shallowly clone an object
const { strictEqual: assertIs, notStrictEqual: assertIsNot } = require('assert');
const { shallowclone, assertEquals, assertUneq } = require('ferrum');
const a = {foo: []};
const b = shallowclone(a);
// The resulting value must be equal to the input, but be a clone
assertIsNot(a, b);
assertEquals(a, b);
// All children are still the same, so mutating them propagates
// to the original element.
b.foo.push(42);
assertIs(a.foo, b.foo);
assertEquals(a.foo, b.foo);
assertEquals(a.foo, [42]);
Version history
- 1.2.0 Support for objects with Symbol keys.
Parameters:
| Name | Type | Description |
|---|---|---|
a |
A |
Returns:
- Type
- A
(inner) size(what) → {Number}
- Source:
- See:
-
Size for examples
Determine the size of a container. Uses the Size trait.
const { strictEqual: assertIs } = require('assert');
const { size } = require('ferrum');
assertIs(size({foo: 42}), 1);
assertIs(size([1,2,3]), 3);
Version history
- 1.2.0 Support for objects with Symbol keys.
Parameters:
| Name | Type | Description |
|---|---|---|
what |
T |
Returns:
- Type
- Number
(inner) typeIsImmutable(t) → {Boolean}
- Source:
- See:
Test whether instance of a given type is immutable.
const assert = require('assert');
const { typeIsImmutable } = require('ferrum');
assert(typeIsImmutable(String));
assert(typeIsImmutable(Number));
assert(typeIsImmutable(Symbol));
assert(typeIsImmutable(undefined));
assert(typeIsImmutable(null));
assert(typeIsImmutable(RegExp));
assert(typeIsImmutable(Function));
assert(!typeIsImmutable(Object));
assert(!typeIsImmutable(Array));
assert(!typeIsImmutable(Map));
assert(!typeIsImmutable(Set));
Parameters:
| Name | Type | Description |
|---|---|---|
t |
Type |
Returns:
- Type
- Boolean
(inner) uneq(a, b) → {Boolean}
- Source:
- See:
-
Equals for examples
Equivalent to !eq(a, b)
const assert = require('assert');
const { uneq } = require('ferrum');
assert(uneq(4, 5));
assert(!uneq({}, {}));
Version history
- 1.2.0 Support for objects with Symbol keys.
Parameters:
| Name | Type | Description |
|---|---|---|
a |
A | |
b |
B |
Returns:
- Type
- Boolean
(generator, inner) values(what)
- Source:
- See:
Get an iterator over the values of a container.
Uses the Pairs trait.
const { values, assertSequenceEquals } = require('ferrum');
assertSequenceEquals(values(['a', 'b']), ['a', 'b']);
assertSequenceEquals(values(new Set([1, 2])), [1, 2]);
assertSequenceEquals(values({foo: 42}), [42]);
Version history
- 1.2.0 Support for objects with Symbol keys.
Parameters:
| Name | Type | Description |
|---|---|---|
what |
T |