DEV Community

Kuncheria Kuruvilla
Kuncheria Kuruvilla

Posted on

Filtering an array against another array conditionally

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"]
Enter fullscreen mode Exit fullscreen mode

and target is

["pen", "pencil", "paper", "", "books", "paperback"]
Enter fullscreen mode Exit fullscreen mode

the result should be

["pen", "pencil", "paper", "paperback"]
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode



Top comments (0)