I have a scenario where I need to grab the first occurrence of a string from an object, but only if the match occurs in one of the path's that have been pre-defined.
{ id: 'I60ODI', description: 'some random description' }
{ foo: 'bar', description: { color: 'green', text: 'some description within text' } }
When provided either of the two objects above, I would expect the solution to return either some random description
or some description within text
, provided that the two possible paths are obj.description
and obj.description.text
. New paths might also need to be added in the future, so it needs to be easy to add them.
Here is the solution I have implemented so far, but to me it doesn't seem optimal.
// require the ramda library
const R = require('ramda');
// is the provided value a string?
const isString = R.ifElse(R.compose(R.equals('string'), (val) => typeof val), R.identity, R.always(false));
const addStringCheck = t => R.compose(isString, t);
// the possible paths to take (subject to scale)
const possiblePaths = [
R.path(['description']),
R.path(['description', 'text'])
];
// add the string check to each of the potential paths
const mappedPaths = R.map((x) => addStringCheck(x), possiblePaths);
// select the first occurrence of a string
const extractString = R.either(...mappedPaths);
// two test objects
const firstObject = { description: 'some random description' };
const secondObject = { description: { text: 'some description within text' } };
const thirdObject = { foo: 'bar' };
console.log(extractString(firstObject)); // 'some random description'
console.log(extractString(secondObject)); // 'some description within text'
console.log(extractString(thirdObject)); // false
I would really appreciate it if a seasoned functional programmer might provide me with some alternative approaches to implementation. Thanks.