-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Predicates
Immutable uses predicate
functions for a few methods including filter
, every
, and count
. Predicates are also used in many JavaScript Array
methods.
Predicates have the signature:
<K, V>(value?: V, key?: K, iter?: Iterable<K, V>) => boolean
Predicates must be pure, always returning the same value based on the given inputs.
How nice of you. Many methods on Immutable collections which accept a predicate have equivalents expecting a predicate which returns the opposite. For example, every
and some
, filter
and filterNot
, skipWhile
and skipUntil
. If you come across a case where using different methods is burdensome but you need the ability to create a complement of a predicate, this builder is useful:
function not(predicate) {
return function() {
return !predicate.apply(this, arguments);
}
}
Another way to express filterNot
:
var data = Immutable.fromJS([ 1, 2, 3, 4, 5 ]);
data.filter(not(x => x % 2 === 0));
// List [ 1, 3, 5 ]
A common usage of filter
is to "pick" a number of keys from a Collection, popularized by underscore and lodash. A helpful predicate builder to have filter behave like pick
:
function keyIn(/*...keys*/) {
var keySet = Immutable.Set(arguments);
return function (v, k) {
return keySet.has(k);
}
}
If you're using ES6, using arguments
in this way won't work.
Instead, use the spread operator :
function keyIn(...keys) {
var keySet = Immutable.Set(keys);
return function (v, k) {
return keySet.has(k);
}
}
Then pick
and omit
looks like:
var data = Immutable.Map({ a: 1, b: 2, c: 3, d: 4 });
data.filter(keyIn('a', 'c')); // pick
// Map { a: 1, c: 3 }
data.filterNot(keyIn('a', 'c')); // omit
// Map { b: 2, d: 4 }