deepFilter
function uses the predicate
to filter properties which may be nested deeply in the given value
(object or array). It returns filtered object or array.
I attempted to use as much FP principles as I could think of and will appreciate any comments on things I did right and wrong (from FP perspective) and suggestions to improve.
const and = (f1, f2) => v => f1(v) && f2(v); const or = (f1, f2) => v => f1(v) || f2(v); const isArray = v => Array.isArray(v); const isObject = v => typeof v === 'object' && v !== null; const hasProps = v => Object.keys(v).length > 0; const selector = (predicate, v1, v2) => v => (predicate(v) ? v1 : v2); const isObjectOrArray = or(isArray, isObject); const hasValue = and(isObjectOrArray, hasProps); const initial = selector(isArray, [], {}); function deepFilter(value, predicate) { if (isObjectOrArray(value)) { return Object.keys(value).reduce((filtered, key) => { if (predicate(key)) { return { ...filtered, [key]: value[key] }; } const v = deepFilter(value[key], predicate); return hasValue(v) ? { ...filtered, [key]: v } : filtered; }, initial()); } return value; }