Functional approach to removing items in a list based on nested values

I am trying to move on to functional programming in my javascript applications. I am currently using the ramda library as the base library for this.

My wish:

  • Create a removeUserFromList function (username, list) that returns items in a list that does not match the username.
  • Make the implementation as short as possible by drawing as much as possible from the existing functions in the Ramda library.

Conditions:

A list containing nested user objects:

[{ providers: { github: { login: "username1" } } }, { providers: { github: { login: "username2" } } }] 

Reached so far:

 var list = [{providers: {github: {login: "username1"}}}, {providers: {github: {login: "username2"}}}]; var getLoginName = R.useWith(R.path('providers.github.login')); var isLoginNameEq = R.useWith(R.eq, getLoginName); isLoginNameEq(list[0], "username1") // => true //From this point on I am totally clueless, //but I believe I should combine these functions //with R.reject in some way. 

Demonstration Plunkr:

http://plnkr.co/edit/1b5FjxV3Tcgz7kozW1jX

Question:

Is there any more suitable function to achieve something similar to R.eq, but to nested objects (possibly R.pathEq)?

+5
source share
3 answers

I just received a transfer request to merge R.pathEq . It will not be used until the next version of ramda.js (the current version is 0.6.0), but for now you can recreate it as follows:

 var pathEq = R.curry(function(path, val, obj) { return R.eq(val, R.path(path, obj)); }); 

And then use it like this:

  var rejectThis = 'userName1'; var myFilter = R.useWith(R.reject, pathEq('providers.github.login'): var filteredList = myFilter(rejectThis, users); 
+6
source

if you don’t need to create a function without dots, you can simply:

 var removeUserFromList= function(name, list) { return R.reject(pathEq('providers.github.login', name), list); } console.log(removeUserFromList('username1', users)); 

using the @Ludwig Magnussen pathEq .

+1
source

Extending the solution from @LudwigMagnusson, a bit, you could do this:

 // terrible name, but I'm never good at that. var rejectPathVal = R.curry(function(path, val, list) { return R.reject(R.pathEq(path, val), list); }); var filteredList = rejectPathVal('providers.github.login', 'userName1', list); 

And of course, you could use it like:

 var myFilter = rejectPathVal('providers.github.login', 'userName1'); // ... var filteredList = myFilter(list); 

or in any way that you choose, given that it is fully loaded. Although, as Ludwig noted, pathEq not part of the released version of Ramda, you can get it by downloading the HEAD version from Github, or you can use the Ludwig version mentioned above.


But I want to ask your requirements a little. I welcome your attempt to move to a more functional style. I am one of the authors of Ramda, and I think this is a great choice for the library, but it seems unnecessary:

Make the implementation as short as possible by drawing on existing functions in the Ramda library as much as possible.

I would suggest that the goals of readability should always surpass those of short duration. Of course, elegance and readability are often associated with multiplicity, but "as short as possible" should never be a driving target.

0
source

Source: https://habr.com/ru/post/1204246/


All Articles