Last active
March 23, 2017 17:39
-
-
Save ianstarz/6867f48e5be41f7b086870374d877f0b to your computer and use it in GitHub Desktop.
Deep filter for nested Immutable Maps and Lists
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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