In this series of articles we look at several practical use cases and see how we can write clean JavaScript in functional style. You might need a little bit of understanding about functional programming and ramda to follow along.
Problem statement
We need to build a function that takes an array of strings as query
and another array of strings as target
. The function should return an array with those strings in target
that starts with any item in query
.
Lets look at an example.
If query
is
["pen", "paper"]
and target
is
["pen", "pencil", "paper", "", "books", "paperback"]
the result should be
["pen", "pencil", "paper", "paperback"]
Solution
Lets look at the final solution first and then break it down.
Our textStartsWith
function takes query
as its argument and returns another function which accepts target
and returns the result.
If we take a look at the pipe function it becomes more interesting
const textStartsWith = pipe(map(startsWith), anyPass, filter);
map(startsWith)
actually creates an array of predicates, each corresponding to the items in query
. This list of predicates is passed to anyPass
. Now what we have is a single predicate with resolves to true
if a given string starts with any of the strings in query
. We can now pass this predicate as an argument to filter. Now when you call textStartsWith
with the list of strings or query
we get back a filter function with the predicate already partially applied. Now all we need to do is pass the target
array as an argument to this function.
P.S. If you need more insights to the solution check out this thread on stack overflow
I would combine startsWith
and anyPass
like this:
const textStartsWith = pipe (
map (startsWith),
anyPass,
flip (o) (String),
filter
)
console .log (
textStartsWith
(['pen', 'paper'])
(['pen', 'pencil', 'paper', '', undefined, true, 'books', 'paperback'])
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js"></script>
<script>const {pipe, map, startsWith, anyPass, flip, o, filter} =
…</p>
Top comments (0)