Do It With Ramda Part I

Find users by name

Consider this array of jedi objects:

const users = [
  { name: "Ahsoka Tano", level: 9 },
  { name: "Darth Vader", level: 8 },
  { name: "Aayla Secura", level: 9 },
  { name: "Yoda", level: 10 },
];

How to return the object whose name matches?

Vanilla JavaScript

function findByName(name, users) {
  return users.find(user => user.name === name);
}

findByName("Aayla Secura", users);
//=> { name: "Aayla Secura", level: 9 }

Ramda

Let"s build this step by step.

Using propEq(), check that the given object (last parameter) contains "Yoda" as the value for the property name in that object.

propEq("Yoda", "name", { name: "Yoda", level: 10 });
//=> true

Note we are hard-coding the name "Yoda". To make the name dynamic, create a function that takes the name (a string) and uses it as the first parameter of propEq().

/**
 * @sig String -> Object -> Boolean
 */
const hasName = name => propEq(name, "name");

hasName("Yoda")({ name: "Yoda", level: 10 });
//=> true

hasName() takes the name as a string, returns a function that takes an object, which un turns returns a boolean indicating whether the name matches or not.

Finally, if we have a collection of jedi, we can use hasName() as find()'s callback finding function:

/**
 * @sig String -> [Object] -> Object | undefined
 */
const findByName = name => find(hasName(name, "name"));

findByName("Yoda")(users);
//=> { name: "Yoda", level: 10 }

findByName("Aayla Secura")(users);
//=> { name: "Aayla Secura", level: 9 }

findByName() takes a string, then it returns a function that takes an array of objects, which in turn returns either the found object (if the name matches) or undefined otherwise.