I’m confused since node => node seems awkward to me.
<ul className="flex gap-2 text-xl">
{menu.menuItems.nodes
->Array.keepMap(node => node)
->Array.map(node => <li key=node.path> {React.string(node.label)} </li>)
->React.array}
</ul>
Minnozz
September 30, 2022, 8:55pm
2
I have written the same thing a few times. Maybe a separate function (keepSomes?) would be clearer.
1 Like
would love to use identity fn but I’m not sure if it exists in rescript
mouton
September 30, 2022, 10:29pm
4
I think if you write this as its own function (We have Array.catOptions), you can write an external identity function that saves you creating a temp function repeatedly. fwiw.
external identity: 'a => 'a = "%identity"
let catOptions = (arr: array<option<'a>>): array<'a> => {
arr->Belt.Array.keepMap(identity)
}
1 Like
johnj
September 30, 2022, 11:05pm
5
Using a map
after keepMap
is partially redundant since you can combine them like this:
<ul className="flex gap-2 text-xl">
{menu.menuItems.nodes
->Array.keepMap(x =>
switch x {
| Some(node) => Some(<li key=node.path> {React.string(node.label)} </li>)
| None => None
}
)
->React.array}
</ul>
It’s more verbose than your original version, but it’s more efficient since you don’t have to map over the array twice.
You can make it more concise with the option helper functions:
<ul className="flex gap-2 text-xl">
{menu.menuItems.nodes
->Array.keepMap(
Option.map(_, x => <li key=x.path> {React.string(x.label)} </li>),
)
->React.array}
</ul>
1 Like
DZakh
October 2, 2022, 8:47am
6
We have a helper for this at Carla
// OptionExtra.res
let values = Belt.Array.keepMapU(_, (. a) => a)
And to ensure that it’s used instead of keepMap
I’ve added a eslint rule:
"no-restricted-syntax": [
"error",
{
"selector": "CallExpression[callee.object.name='Belt_Array'][callee.property.name='keepMap'] > FunctionExpression[body.body.0.type='ReturnStatement'][body.body.0.argument.type='Identifier']",
"message": "Use OptionExtra.values instead."
},
]
1 Like