pick.js

import {
  deepMapOutwards
} from './map';

import {
	asList,
	isLeaf,
	pick
} from './utils';

/**
 * @module pick
 */

/**
 * Once fully applied, this returns a new tree containing only nodes lying on the supplied `nodePath`, with all nodes and children outside of the `nodePath` removed.
 *
 * @param {NodePath} nodePath A `NodePath` whose nodes will be filtered and returned.
 * @param {ChildPath} [childPath=null] An `Array` or `List` of keys indicating where to find each node's children from within each node.
 * @return {InputFunction} A partially applied function which accepts a single tree `Iterable`, and returns the modified tree `Iterable`.
 */

function deepPick(nodePath, childPath=null) {
  nodePath = asList(nodePath);
  childPath = asList(childPath);

  return (tree) => tree.update(deepMapOutwards((item, mapNodePath) => {
  	const childKeys = mapNodePath.size < nodePath.size
  		? [nodePath.get(mapNodePath.size)]
  		: [];

  	return isLeaf(item, childPath)
      ? item
  		: item.updateIn(childPath, kids => pick(kids, childKeys));

  }, childPath));
}

export {
  deepPick
}