In this lesson, we'll grab arrays of values from other arrays, resulting in a nested array. From there, we'll look at multiple ways to flatten the array structure using composition with
unnest and then refactoring to use
flatMap. Finally, we'll add Ramda's
uniq function to remove duplicate values.
I then put in the ramda library and I'm using destructuring to grab its propmap and compose functions. I also have a sample product object. The product contains an array of size objects and each size has a name and a colors property. That colors property is an array of objects representing colors each with its own name property.
Our goal is to get a unique list of color values that are available for this product independent of what size each color belongs to. I've started off by defining a function called getsizes which is just using ramda's prop function with the value sizes passed into it. When I pass the product to it I get back an array of those size objects.
Next, let's define a getcolors function and say constgetcolors. This is going to get our colors property, so we'll be able to use prop passing it colors. We want to get this off of each item in that sizes array, which means we want to map over this and then we can define colors.
We'll make that a call to getcolors using our sizes value from the previous function call, and then we'll log this out to see where we're at. I'll save this and in the terminal I'll run it. You'll see that we get back an array of arrays, and each entered array is an array of those color objects.
Now that we're getting the colors back all I really need from each color is the name. I'm going to come up here and to clear a new constant I'm going to call a getcolornames. This is going to be another function that maps. We're going to have to map because we're still dealing with nested arrays.
For each entered array we want to call pluck, which is going to grab our property, in this case name, off of each object in that array of objects. I just need to add pluck to my destructuring up here to make sure it's available. Then I need to use my function to get my values.
We'll call colornames and that will be the result of calling getcolornames, passing in colors from the previous function call. Now that that's setup I'm just going to come down here and I'm going to update this so that our result is now colornames. I'll save it, jump into the terminal, run it and we'll see that we get back nested arrays, but now we're down to just the string values for the names.
Before we take this any further we should take a look at what we're doing here. There's a pattern where we're basically declaring a function, getting results by passing in a piece of data, and then taking those results and passing them into the next function.
What we have here is a perfect candidate for composition. Let's take out these intermediate values, and for now I'll just comment them out. I'm going to define a new function, so const will say getuniquecolors.
We're going to set this to a composition, so I'm going to use ramda's compose. I don't want to compose all the functions that we've created so far, so we'll do getcolornames and before that we want to call getcolors, and before that we want to call getsizes.
Now our result, it can be a call to getuniquecolors. We'll pass in our product. We'll save that. I'll jump into the terminal, we'll make sure that works. We're getting the same result that we got before, so that's great.
Now, I can come in here and I can get rid of these intermediate values. Bring this up a little bit. Now I have this nice composition that takes my data and passes it all the way through to the result. Now that we've cleaned this up we still need to deal with the fact that we have nested arrays.
If we look getcolors is where our arrays end up getting nested, because we're pulling sizes, and then from within each one of those size objects we're pulling out colors, which is an array, so we end up with this array of arrays. In order to use pluck we have to map again because we still have those nested arrays.
Ideally at this step we'll be able to take those nested arrays and unnest them. Ramda has a function called unnest and we can pull that in here. We can update this to be a composition, where we map to our props, we get our nested array. Then we unnest that value. That would allow us to get rid of this map.
If we take a look at this in the terminal we'll see that we get a flat array of just our values. The other way I can handle this is get rid of unnest altogether, we'll take it out of here and instead I'm going to pull in chain. Then I'm going to replace my map right here with chain.
Chain is essentially flat map. That's going to do what our composition of map and unnest did, except it's going to do it over the single function, and then I no longer need map. I can save this and back in the terminal. I can run it, and I get my flat results.
The only thing we're missing from this is the fact that we don't have our unique values, you'll see that blue is repeated, so I can pull in another ramda function called unique. Then I can add this to my composition.
If I jump back in the terminal and run this one more time we'll see that I've removed that duplicate blue, so now I have the unique color names from this product independent of the sizes that those colors belong to.