I tried:
let arrayOfValues = arrayOfOptions |> Js.Array.filter(a =>
switch(a) {
| Some(_) => true
| None => false
});
but arrayOfValues
still contains optionals.
I tried:
let arrayOfValues = arrayOfOptions |> Js.Array.filter(a =>
switch(a) {
| Some(_) => true
| None => false
});
but arrayOfValues
still contains optionals.
Belt.Array.keepMap
applies a function to each element of an array and keeps only the values for which the function returns Some(value)
; since your array already consists of optionals, a function that returns the item unchanged will do exactly what you need.
let arr = [|Some(3), None, Some(5), None, Some(7)|];
let filtered = Belt.Array.keepMap(arr, fun (x) => x);
Js.log(filtered); /* produces [|3, 5, 7|] */
That’s exactly what I was looking for. In my searches I found filter_map
but it looks like it’s for Lists and only supported in OCaml.
@jdeisenberg I have a follow about question about Belt.Array.keepMap
, is there a way to use it with |>
? I guess I could define a function which reverses the params, but it seems weird to have to do that. Is there a reason why Belt.Array
functions accept the array as the first param?
There’s a special notation |.
to pipe to the first argument:
/* dummy function that produces an array of optional ints */
let makeArr = () : array(option(int)) => {
[|Some(3), None, Some(5), None, Some(7)|];
};
let filtered = makeArr() |. Belt.Array.keepMap(fun (x) => x);
You can also use |>
with _
to replace any specific argument you want, but somewhere I read it is not as performant as |.
let filtered = makeArr() |> Belt.Array.keepMap(_, fun (x) => x);
Belt is probably the way to go - but here’s another way -
/**
* Given an array or a list of options, return only the
* items that are Some(item)
**/
let arr_only_some = (arr) => Array.fold_right(
(x, result) =>
switch x {
| Some(i) => Array.append([|i|], result)
| None => result
},
arr,
[||]
);