Skip to content

Instantly share code, notes, and snippets.

@ianstarz
Last active March 23, 2017 17:39
Show Gist options
  • Save ianstarz/6867f48e5be41f7b086870374d877f0b to your computer and use it in GitHub Desktop.
Save ianstarz/6867f48e5be41f7b086870374d877f0b to your computer and use it in GitHub Desktop.
Deep filter for nested Immutable Maps and Lists
import Immutable from 'immutable';
const { isIterable } = Immutable.Iterable;
const { isMap } = Immutable.Map;
const { isList } = Immutable.List;
const isLeafNode = (node) => {
if (!isIterable(node)) {
return true;
}
if (node.size === 0) {
return true;
}
return false;
};
/**
* Like Immutable.Map.filter except traverses all Maps in a data structure
* of deeply nested Maps and Lists. For example:
*
* ```
* import Immutable from 'immutable';
* import { immutableDeepFilter } from 'nl-react/state/utils';
*
* const KEY_TO_DELETE = 'some-key';
* const iterable = Immutable.fromJS({
* [KEY_TO_DELETE]: '',
* foo: {
* [KEY_TO_DELETE]: '',
* bar: [
* {
* [KEY_TO_DELETE]: '',
* foo: 'bar'
* }
* ]
* }
* });
*
* const filteredIterable = immutableDeepFilter(
* iterable,
* (value, key) => key === KEY_TO_DELETE
* );
*
* console.log(filteredIterable.toJS());
* // => {
* foo: {
* bar: [
* { foo: 'bar' }
* ]
* }
* }
* ```
*
* @author istorz
* @param {Iterable} node - the Map or List to deeply filter
* @param {String} predicate - filtering function
* @return {Iterable} the deeply filtered iterable
* @see ./deep-filter.spec.js
*/
const deepFilter = (node, predicate) => {
if (isLeafNode(node)) {
return node;
}
return node.withMutations((mutableNode) => {
if (isList(mutableNode)) {
mutableNode.forEach((value, index) => {
mutableNode.update(
index,
currentValue => deepFilter(currentValue, predicate)
);
});
}
if (isMap(mutableNode)) {
mutableNode.forEach((value, key) => {
if (predicate(value, key)) {
mutableNode.delete(key);
} else {
mutableNode.update(
key,
currentValue => deepFilter(currentValue, predicate)
);
}
});
}
});
};
export default deepFilter;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment