Sometimes you just need a subset of an object. In this lesson, we'll cover how you can accomplish this using Ramda's pick and omit functions, as well as the pickAll and pickBy variants of pick.
Here, I've included the Ramda library, created a very simple product object. I have an empty result, and I have a log statement ready to log out that result.
Let's say I want result to be a new object that just has the name and price properties from product. I can go up here, and I can use Ramda's pick function. Pick is going to take an array of property names. I'm going to say name and price, and then I'll pass it the product object. If I jump into the terminal, and I run this, I'll get back an object that has the name and price properties from my product object.
Now I want to jump back into the code, and I want to take advantage of Ramda's automatic function currying. I want to this r.pick, and I want to cut this. I'm going to assign this to get props. I'm just going to have a generic function that we can call with any object that has these properties, and get the same subset back.
If I save that, and I run it, we'll see that everything still works the same way it just did. Since I have a reusable function that I could pass any product into, let's say I also expect it to have a category property that I want to pick as part of my subset.
I'll come up here, and I'll just add category to my list of property names. I'll run that again, and you'll notice that I get name and price back, but I don't get category, because it doesn't exist on the product. Obviously, if this product object had a category property, it would have been included.
Let's say sometimes I have categories. Sometimes I don't. I always want my resulting object to have the same shape, even if it means category is undefined. I can jump back into the code, and I can change this pick to a pick all.
When I run that, you'll see that I get back category with the value undefined. Sometimes you might want to pick properties in a more programmatic way. Let's jump back to the code. I'm going to duplicate get props, and comment out the old one for reference.
I'm going to drop down here, and I'm going to get rid of this array of property names. I'm going to change pick all to pick by. Pick by is going to take a predicate function. I'm going to come in here, and I'm going to say that I want any value that's numeric.
All I have to do is take the value, pass it into number, and it'll give me back numeric properties only. If I save this, I jump into the terminal, and I run it, you'll see that I get back an object that only has the price property.
If I jump back to the code, I give this object another property -- let's say average rating -- and I set that to 4.5, and I run this again, I'll get back an object that has both price and average rating, because they both have numeric values.
With pick by, we're not limited to making decisions based solely on the property's value. The predicate function receives the value, but it also receives the properties key. Let's take a look at how we can use that.
I'm going to drop down here, and I'm going to duplicate that line, and keep the old one for reference. I'm going to update this predicate function to take both val and key. Let's say that rather than numeric values, I want to get anything related to shipping.
I'm going to say r.contains shipping, and I'm going to pass that key. That should return a true for any key that has the word shipping in it. If I save this, go back into the terminal, and run it, you'll see that we get back an object that only has shipping weight.
Let's go back into the code, and just to make sure this works properly, I'm going to add a shipping cost property. We'll say shipping is two dollars. I'll jump back, run it, and this time, my object has shipping weight and shipping cost.
You might have cases where, instead of choosing what to include in the object, you want to choose what to exclude. I'm going to jump back to the code, and show you how you can do that. I'll come down here, comment out get props, and create a new one.
This time, I'm going to set it to equal call to r.omit. Omit is going to take an array of property names, just like the original pick function did. I'm going to pass this shipping weight, and a second string, shipping cost.
When I save this and run it, I'll get back an object that has name, price, and average rating, but it excludes the shipping weight and the shipping cost properties. Omit doesn't have a variant called omit by, where we can pass it a predicate, like we could with the pick by function.
We can accomplish the same kind of thing using pick by. Let's say I want to omit anything related to shipping without having to list out all the property names. I can comment this out, I'm going to go up here, and I'm going to grab that last pick by function we created.
Create a copy of that, uncomment it. You'll see here that we're basically grabbing that anything that contains shipping, and we're including that in our object. Omitting anything that contains shipping is as simple as negating our call to r.contains in that predicate function.
I can save this, jump back into the terminal, and when I run this, I'm going to get back everything but shipping weight and shipping cost. Just to prove that it works programmatically, I'm going to add shipping method as a property.
When I run this, it should return the same results as last time, leaving out all three of the shipping related properties.