Here is a simple chained expression using modern javascript to find the value for a specific key located in a string containing a comma separated list of key-value pairs separated by =
.
This falls down if the source is null or the key is not found, in my head this seemed like a great task for the Maybe monad.
// Grab the tag with key in `tag`
const getTag = (product, tag) =>
product.Tags
.split(',')
.find(t => t.startsWith(`${tag}=`))
.split('=')[1]
getTag({Tags: 'a=y,b=z'}, 'a') // returns 'y'
getTag({Tags: 'a=y,b=z'}, 'z') // returns boom (desired null)
getTag({Tags: null}, 'a') // returns boom (desired null)
So I npm installed sanctuary and began playing with a functional solution. This is as far as I've gotten so far and fee like it's pretty ugly, this tells me I must be doing something wrong or using the wrong tools.
const getk = S.map(S.filter(S.test(/=/)))(S.splitOn(','))
S.map(S.map(S.map(S.splitOn('='))))(S.map(getk))(S.toMaybe(null))
// Nothing
S.map(S.map(S.map(S.splitOn('='))))(S.map(getk))(S.toMaybe('a=y,b=z'))
//Just ([["a", "y"], ["b", "z"]])
I didn't want this to be a "solve this problem for me" question, but I am having a difficult time conveying what it is that I actually need help on.
N.B. I'm still trying to "figure out" FP, so this is definitely a problem of familiarity.
We can use
S.map
to transform inner values andS.join
to remove unwanted nesting:S.map
followed byS.join
is always equivalent toS.chain
:This approach does a bit of unnecessary work by not short-circuiting, but
S.stripPrefix
allows us, in a single step, to check whether the tag exists and extract its value if it is. :)Updated version which uses
S.justs
to select the first match: