Q:

Is value in array or string inside object Ramda

A little bit of an odd one here, I’m working with parsing query strings and sometimes they are returned as strings and other times as arrays of strings (depending on if there’s one vs. many).
I want to find out whether the value exists under the key, and it needs to work when the data is empty or null.
# we have access to both the key and value
const key = 'locations'
const value = 'London'

The shape of the data looks like:
# does 'London' exist under `locations`?
{
  locations: 'London',
  skills: ['1', '2'],
}

The shape of the data could also look like:
{
  locations: ['London', 'Reading'],
  skills: '1',
}

I’ve looked at using pathSatisfies, pathEq and contains but with no luck. I seem to be getting stumped on the fact the value can be contained in either a string or in an array. 

A:

I'd use a lens to convert the key into an array if it wasn't one already. Then you can simply use propSatisfies with includes:

const toArr = unless(is(Array), of);

const check = (key, value) =>
  pipe(
    over(lensProp(key), toArr),
    propSatisfies(includes(value), key));

console.log(
  check('locations', 'London')({locations: ['London', 'Reading']})
);

console.log(
  check('locations', 'London')({locations: 'London'})
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.min.js"></script>
<script>const {unless, is, of, pipe, over, lensProp, propSatisfies, includes} = R;</script>

EDIT: Actually this can be simplified as includes work with both strings and arrays:

const check = (key, value) => where({[key]: includes(value)})

console.log(
  check('locations', 'London')({locations: 'London'})
);

console.log(
  check('locations', 'London')({locations: ['London', 'Reading']})
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.min.js"></script>
<script>const {where, includes} = R;</script>

