Skip to content
Sandwich on brown bread with lettuce, cheese, ham and tomato

Top 10 Ramda Functions at Media Suite

To help you on your path to functional greatness, here are our picks for the top 10 functions from the Ramda library.

The latest version of Ramda contains 235 individual functions.

To help you on your path to functional greatness, here are our picks for the top 10 functions from the Ramda library. We’ve used these across three large, complex web applications developed at Media Suite. The method used for collecting this data is tracked here.

A key concept in functional programming is writing functions that work on other functions. One of the most important examples of this is the concept of currying.

Consider this example:  We have a regular function add  which we pass as an argument to R.curry . The result of this is a function which can not be called without passing in all of the defined parameters. When addCurried(1)  is called, we get a version of the  add function where the first parameter is always the value “1”. All functions in the Ramda library are curried by default.

const add = (a, b) => a + b
console.log(add(1, 2))
// > 3
const addCurried = R.curry(add)
const addOne = addCurried(1)
console.log(addOne(9))
// > 10

R.propEq

This function takes three parameters: a property name (string), a value and an object. It checks if the property name on the object is equal to the value provided. Most of the time, this function is used in a filter clause  or if clause .

const isCircle = R.propEq('type', 'circle')
const shapes = [
{ type: 'circle', width: 10, height: 10},
{ type: 'square', width: 10, height: 10},
]
console.log(isCircle(shapes[0]))
// > true
console.log(isCircle(shapes[1]))
// > false

R.merge

This function is similar in function to Object.assign. It expects two object arguments and returns an object. The behaviour is to merge all fields from the right hand object into the left hand object. This is typically used within a “map” function to apply fields to another object.

const circle = { type: 'circle', width: 10, height: 10}

const boldBorder = R.merge({ border: '5px' })

console.log(boldBorder(shapes[0]))

// > { border: '5px', type: 'circle', width: 10, height: 10}

R.isNil

Part of writing good reusable functions is checking that the correct parameters are used. R.isNil  lets us check if the value is nil or undefined. In our projects over the last year we have used this function 79 times.

R.isNil(null) // > true

R.isNil(undefined) // > true

R.isNil(0) // > false

R.isNil("functions are great") // > false

R.filter

This works like Array.prototype.filter, but with more currying and switched around parameters to what you may expect, coming from other utility libraries like lodash. It expects two parameters. First, a function which takes one parameter and returns truthy or falsy values. Second, an array. We use this function frequently to get the right array of things before passing that array into another function for further processing.

const shapes = [
{ type: 'circle', width: 10, height: 10},
{ type: 'square', width: 10, height: 10},
]

const getCircles = R.filter(isCircle)

console.log(getCircles(shapes))

// > [{ type: 'circle', width: 10, height: 10}]

R.pluck

At number four out of 10, we used the pluck function, 111 times. It takes a string and array of objects as parameters. The return is an array of values picked out from each object in the input array.

const shapes = [
 { label: 'Fierce Circle', type: 'circle', width: 10, height: 10},
 { label: 'Obtuse Square', type: 'square', width: 10, height: 10},
]

const getLabels = R.pluck('label')

console.log(getLabels, shapes)

// > ['Fierce Circle', 'Obtuse Square']

R.map

Map takes the same parameters, and returns the same type of value as filter. They are best friends. Often the output of a map is the input to a filter (or vice versa). It was used 200 times.

const shapes = [
{ label: 'Fierce Circle', type: 'circle', width: 10, height: 10},
{ label: 'Obtuse Square', type: 'square', width: 10, height: 10},
]

const isSquare = R.propEq('type', 'square')
const getSquares = R.filter(isSquare)
const getAreas = R.map(shape => shape.width * shape.height)

console.log(getArea(getSquares(shapes)))
// > [100]

R.pipe

In the previous nine functions I have demonstrated, we have made some neat little functions. Using currying, these functions now operate on a single value. To use a food as an analogy, R.pipe  is the bread holding our tasty functions together to make a delicious sandwich.

In the previous example we used getArea , getSquares  and finally console.log  to print the results. The problem with nesting functions like this is that our eyes have to scan in an un-natural way to figure out how the data flows through functions.  We have to find the value shapes , then scan each function to the left to understand the how the function operates on that parameter. The following example shows how we can create the same function by using pipe.

const printSquareAreas = R.pipe(
getSquares,
getAreas,
values => console.log(values)
)
printSquareAreas(shapes)

Banner image: Photo by Mae Mu on Unsplash 

Media Suite
is now
MadeCurious.

All things change, and we change with them. But we're still here to help you build the right thing.

If you came looking for Media Suite, you've found us, we are now MadeCurious.

Media Suite MadeCurious.