7 Ramda recipes
Useful function combinations
When working on a new project where I use Ramda I find myself creating a bunch of simple function which helps me better express my intent. Usually, those functions are a just simple combination of two or three of basic blocks provided in Ramda. Below is my top 7.
contained
Ramada provides useful function contains
which abstracts common JavaScript pattern of haystack.indexOf(needle) !== -1
. I find myself that I often need to switch the arguments order. That way I can build a function checking if given item belongs to a set of valid set of values.
Code
const contained = flip(contains);
Example
const validResponse = contained(['success', 'failure']);
if (validResponse(response)) {
// ...
}
filterT
Ramda’s filter
function expects two arguments. First, one is predicate and second a list of values. I find myself often checking if the list contains only truthful values, which can be simplified by creating function I call filterT
(filter all Truth values).
Code
const filterT = filter(identity);
Example
if (filterT([true, 1, false, '']).length > 0) {
// ...
}
allT
Similarly, to filterT
there’s often the need to check if an array contains only truth values.
Code
const allT = all(identity);
Example
if (allT([1, 0, 1])) {
// ...
}
safeHead
By default head
is looking to get the first element of an array. The problem comes when the thing being checked for is not an array (most often an undefined returned when the property is missing). It would be nice if the code would not fail because of that.
My safeHead
differs greatly from what would be a canonical implementation in Haskell, where the return value would be of type Maybe
. It is possible to use that type in JavaScript but it is bit more complicated than what I usually need to do.
Code
const safeHead = compose(head, defaultTo([]));
Example
const obj = {foo: [1, 2, 3]};
const h = safeHead(obj.bar);
toTitle
Ramda contains toUpper
and toLower
which reflect JavaScript String’s object methods. Unfortunately, by default, there’s no way to the uppercase first letter of a string.
The code is not really converting whole string to title case, rather than just the first word. So far I found it useful enough.
Code
const toTitle = compose(
join(''),
over(lensIndex(0), toUpper)
);
Example
console.log(toTitle('test')); // => "Test"
imap
One difference between using Ramda’s map
and built in Array’s map is the lack of access to the element index. In most cases it’s not a problem. So far my most frequent use case was with React.js and creating a list of nodes. Each one of those nodes requires unique key and array index usually is a perfect solution. With imap
it still can be used.
Code
const imap = addIndex(map);
Example
<ul>
{imap((el, i) => <li key={i}>{el.text}</li>, elements)}
</ul>
peek
Especially useful when debugging is an ability to inspect the value in a series of function applications.
Code
const peek = tap(console.log);
Example
// ...
const process = compose(
save,
peek,
transform,
retrieve
);
// ...
process('12');