Usage of 2 arrow symbol in "filter" method

I’ve come across below filter usage which I didn’t understand

const byQuery = query => item =>
  !query || item.name.toLowerCase().includes(query.toLowerCase());
  1. byQuery is suppose to return new array which has got matching string with query

  2. Why 2 => are used here ?

  3. item represents each array element

Each => represents another function call. So it’s a function that takes a query and returns another function that takes the items.

const byQuery = query => item =>
  !query || item.name.toLowerCase().includes(query.toLowerCase());


const includesDog = byQuery('dog')

console.log(['cat-mouse', 'dog-cat', 'pig-chicken'].map( item => includesDog(item))

This pattern is common in functional programming libraries as an alternative to a single function that takes two arguments like byQuery('dog', items).

Unary functions are able to be written in point free style, since they take a single argument - arrayOfItems.filter(includesDog) is the same as arrayOfItems.filter(item => includesDog(item)). This is only true for functions that take a single argument.

So one of the advantages of writing functions like (x) => (y) => x + y is that they can be written in point free style. Here is another example to illustrate.

const addX = (x) => (y) => x + y
const addTen = addX(10)

console.log([1,2,3,4,5].map(addTen))
2 Likes

Thanks for detailed clarification.

But I didn’t understand usage of !query .. in above code ?

How does !"dog".. works or why is it needed to be used in this scenario ?

Coming from Java world, JS is quite confusing many a times :slightly_smiling_face:

This ! is the not operator and it returns a boolean value, if the value is falsey it returns true else it returns false.

This !query || item.name.toLowerCase().includes(query.toLowerCase()); is using the || operator in what is called short circuiting. If the left hand side is true in the case of a || short circuit the code immediately stops execution so if query were to be a falsey value then the function returned by byQuery would return true, and never execute the rest of the function.

Personally I don’t get why they are doing !query because that means they are returning true for a value that the given object probably does not have which is strange considering that they return false if the given value at name does not include a truthy query

const byQuery = query => item =>
  !query || item.name.toLowerCase().includes(query.toLowerCase());

const includesDog = byQuery('dog')

includesDog({name: 'dog'}) //returns true

includesDog({name: 'fhj'}) //returns false

byQuery('')({name: 'fjah'}) 
//will return true no matter what I hand to the second function

Here are some resources:

1 Like

Thanks for detailed clarification

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.