Deep filter value using functional programming principles

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
1
down vote

favorite












deepFilter function uses a predicate to filter properties which may be nested deeply in the given value (object or array). It returns filtered object or array.



The code works for most inputs (arbitrary levels of nesting and input without cyclic references). I'm more interested in comments on my approach to FP than correctness of the code. Though I wouldn't mind if you point a mistake.



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(value));

return value;







share|improve this question

















  • 1




    Problem with your code is that many JavaScript objects are cyclic, and you do not check. eg Try and run deepFilter(window, v => v === "somePropertyName");
    – Blindman67
    Feb 10 at 20:16










  • Good catch. I need to see how I can work around those situations. Thanks.
    – Nishant Shreshth
    Feb 11 at 18:12
















up vote
1
down vote

favorite












deepFilter function uses a predicate to filter properties which may be nested deeply in the given value (object or array). It returns filtered object or array.



The code works for most inputs (arbitrary levels of nesting and input without cyclic references). I'm more interested in comments on my approach to FP than correctness of the code. Though I wouldn't mind if you point a mistake.



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(value));

return value;







share|improve this question

















  • 1




    Problem with your code is that many JavaScript objects are cyclic, and you do not check. eg Try and run deepFilter(window, v => v === "somePropertyName");
    – Blindman67
    Feb 10 at 20:16










  • Good catch. I need to see how I can work around those situations. Thanks.
    – Nishant Shreshth
    Feb 11 at 18:12












up vote
1
down vote

favorite









up vote
1
down vote

favorite











deepFilter function uses a predicate to filter properties which may be nested deeply in the given value (object or array). It returns filtered object or array.



The code works for most inputs (arbitrary levels of nesting and input without cyclic references). I'm more interested in comments on my approach to FP than correctness of the code. Though I wouldn't mind if you point a mistake.



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(value));

return value;







share|improve this question













deepFilter function uses a predicate to filter properties which may be nested deeply in the given value (object or array). It returns filtered object or array.



The code works for most inputs (arbitrary levels of nesting and input without cyclic references). I'm more interested in comments on my approach to FP than correctness of the code. Though I wouldn't mind if you point a mistake.



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(value));

return value;









share|improve this question












share|improve this question




share|improve this question








edited Feb 11 at 18:52
























asked Feb 10 at 12:28









Nishant Shreshth

1062




1062







  • 1




    Problem with your code is that many JavaScript objects are cyclic, and you do not check. eg Try and run deepFilter(window, v => v === "somePropertyName");
    – Blindman67
    Feb 10 at 20:16










  • Good catch. I need to see how I can work around those situations. Thanks.
    – Nishant Shreshth
    Feb 11 at 18:12












  • 1




    Problem with your code is that many JavaScript objects are cyclic, and you do not check. eg Try and run deepFilter(window, v => v === "somePropertyName");
    – Blindman67
    Feb 10 at 20:16










  • Good catch. I need to see how I can work around those situations. Thanks.
    – Nishant Shreshth
    Feb 11 at 18:12







1




1




Problem with your code is that many JavaScript objects are cyclic, and you do not check. eg Try and run deepFilter(window, v => v === "somePropertyName");
– Blindman67
Feb 10 at 20:16




Problem with your code is that many JavaScript objects are cyclic, and you do not check. eg Try and run deepFilter(window, v => v === "somePropertyName");
– Blindman67
Feb 10 at 20:16












Good catch. I need to see how I can work around those situations. Thanks.
– Nishant Shreshth
Feb 11 at 18:12




Good catch. I need to see how I can work around those situations. Thanks.
– Nishant Shreshth
Feb 11 at 18:12















active

oldest

votes











Your Answer




StackExchange.ifUsing("editor", function ()
return StackExchange.using("mathjaxEditing", function ()
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
);
);
, "mathjax-editing");

StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "196"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);








 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f187249%2fdeep-filter-value-using-functional-programming-principles%23new-answer', 'question_page');

);

Post as a guest



































active

oldest

votes













active

oldest

votes









active

oldest

votes






active

oldest

votes










 

draft saved


draft discarded


























 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f187249%2fdeep-filter-value-using-functional-programming-principles%23new-answer', 'question_page');

);

Post as a guest













































































Popular posts from this blog

Python Lists

Aion

JavaScript Array Iteration Methods