1. 9
    Build a Functional Pipeline with Ramda.js
    5m 37s
⚠️ This lesson is retired and might contain outdated information.

Build a Functional Pipeline with Ramda.js

Andy Van Slaars
InstructorAndy Van Slaars
Share this video with your friends

Social Share Links

Send Tweet
Published 8 years ago
Updated 2 years ago

We'll learn how to take advantage of Ramda's automatic function currying and data-last argument order to combine a series of pure functions into a left-to-right composition, or pipeline, with Ramda's pipe function.

[00:00] Here, I've included the Ramda library, and set up some sample data, an array of objects with a "name" and a "score" property each. We want to create a function that will take the top scoring team and return only the name. When we're done with our function, the end result should be the string "Bears."

[00:17] I'm going to drop-down here, and I'm going to set up a function. I'm going to set that function to take an array of Teams. We can see our progress as we go. I'm going to drop-down here, and I'm going to set "const RESULT = getTopName()," and I'm going to pass it in that Teams array. I'm going to log out RESULT.

[00:43] Let's start putting our function together. The first step I want to perform is taking a Teams array and sorting it in descending order by score. It will essentially put the Bears object at the top of the array. I'll declare a variable to hold the result of that.

[00:58] To handle the sorting, I'm going to use Ramda's "sort" function. We'll call r.sort; sort's first argument is a function that's going to take two items from the array at a time. We'll refer to those as A and B. Because we want to sort descending by score, I'm going to take B.score and subtract A.score.

[01:22] The second argument that "sort" needs to do its job is the list that it's sorting, so I'll pass that to Teams, and I'll just return sorted for now, so we can see what's happening. If I run this, we'll see that we get our array back, sorted properly.

[01:40] Now that we've sorted our array, we need to grab the first item because we know that's the highest scoring team. We'll call that topTeam. I'm going to use Ramda's "head" function, which is essentially just going to grab the zero index off an array. I'll pass that the sorted array. We can see the results of that. I'll return topTeam. Run that, and we get the Bears object.

[02:14] The last step I need to perform is to grab the name property off of that object. I'll create a constant called TOPNAME. I could call topTeam.name here, and assign that, and return that value, but I'm going to use another Ramda function called "prop;" prop is going to take the name of a function and an object, and return the value of that property.

[02:36] I want to get the "name" property from topTeam, I want to return that, and run it. We get back "Bears."

[02:52] Looking at this, you might be wondering why we didn't just use the built-in "sort" function on a JavaScript array, use the zero index to get the "head," and just call ".name" to get the name back.

[03:06] Ramda does something really cool. Every function of Ramda is automatically curried. What that means is that I can take this "sort" function that takes two arguments. I can pass it just the first argument, which is that sorting function. I'm going to do that. I'm going to move that out here.

[03:23] What's going to happen is when "sort" gets a single argument and it expects two, it's going to take the first argument, keep that in a closure, and return a new function. This "sortByScoreDescending" is a function now that will take any object or any array of objects with a score property, and sort them in descending order.

[03:53] Now, I can take that and I can move that back in here. I can call "sortByScoreDescending" on Teams; "head" only takes one argument, so there's not a whole lot to do there, but I can do the same thing with "prop" and I can basically create a function by calling r.prop with just the first argument.

[04:16] It will return a function that's going to take any object as its argument and return the name property. Now, I can call getName on topTeam.

[04:32] Just to verify that everything still works as expected, let me jump back into the terminal and run that. You'll see we still get Bears back. What this has allowed us to do is boil this process down into three steps, where all we have to do is pass data to each function. The data that we pass to the function is the result of the step before it.

[04:53] What I can do is I can go in here, and I'm going to drop getTopName down. I'm going to comment that out for reference. What I can do is replace getTopName with a much cleaner call to Ramda's "pipe" function, and "pipe" is going to take a series of functions.

[05:11] We're going to do the same three steps. Pipe will take our data, pass it to the first function, take the result of that, pipe it into the next function, and it will continue taking the result of the previous function, passing it into the next until it hits the last function, and that's your result.

[05:31] If I jump into the terminal, I can verify that everything still works as expected. My RESULT is still "Bears."

Charles
Charles
~ 7 years ago

the code in CODE TAB does not reflect what the presenter in the video was teaching. Is there a reason why/

Andy Van Slaars
Andy Van Slaarsinstructor
~ 7 years ago

Charles,

First of all, thanks for watching!

The code in the code tab does have a couple of slight differences, but the core result of the lesson is represented. The key differences are that in the video, I am running the code with Node and use a require to import the library. In the embedded example, Ramda is being pulled into the browser through a script tag.

The second difference is that there is an additional line at the bottom of the code sample, simply for the purpose of showing the results in the result pane rather than forcing you to open your console.

The third difference is that the commented out version of the code has been removed from the embedded example for clarity.

I hope this helps and thanks again for watching!

Sen P
Sen P
~ 7 years ago

Slightly concise version using reduce.

const findTopTeam = R.reduce((a,b) => a.score > b.score ? a : b, {score: 0})
const getName = R.prop('name')
const getTopName = R.pipe(findTopTeam, getName)
Andy Van Slaars
Andy Van Slaarsinstructor
~ 7 years ago

Sen,

Nice optimization!

Markdown supported.
Become a member to join the discussionEnroll Today