What does '!!~' do in Javascript? [duplicate]

I saw following piece of code on github.

/** * Filters an array of objects with multiple criteria. * * @param {Array} array: the array to filter * @param {Object} filters: an object with the filter criteria as the property names * @return {Array} */ function multiFilter(array, filters) { const filterKeys = Object.keys(filters); // filters all elements passing the criteria return array.filter((item) => { // dynamically validate all filter criteria return filterKeys.every(key => !!~filters[key].indexOf(item[key])); }); } 

I don't understand, what does !!~ do here?

PS: I know C and C++ languages and but I'm newbie with Javascript. I know about that operators but I don't understand, Why does use double negation(!!) with bitwise not(~) operator?

6

4 Answers

indexOf will return the index 0-x if the element is found, -1 otherwise.

~ will change all the bits in the number, turning -1 to 0 (the binary represantation of -1 is 1111 1111 ...).

0 is a falsy value, all other numbers are truthy.

!! will convert a falsy value to false and a truthy value to true. It wouldn't be needed here, because every doesn't care whether it recieves a truthy value or true.

As others have mentioned, nowadays you could use includes. However, includes is newer to the JavaScript ecosystem than indexOf, so this solution would work in IE, the solution with include would not. You could still use includes in IE either by providing a polyfill or by transpiling your code.

The tilde turns the resulting indexOf expression truthy if the item is found, and falsey if the item is not found. The !! then converts the result to a boolean from a number. (which is not useful at all, since every only cares about whether the result is truthy or falsey)

It's terribly unclear. It would be much better to use this instead:

return array.filter((item) => { // dynamically validate all filter criteria return filterKeys.every(key => filters[key].includes(item[key])); }); 
3
var fruits = ["Banana", "Orange", "Apple", "Mango"]; var a = ~fruits.indexOf("Banana"); var b = !a; var c = !!a; console.log('a:',a); console.log('b:',b); console.log('c:',c);

It can be break into steps as above to trying to understand what's going on. Bitwise operator: ~ is a common way to replace the ugly 0/-1 comparison when using indexOf method. A double negation using !! will gives us a Boolean to tell whether it's found or not found

!!~ means bitwise not ~ followed by double negation !!.

Bitwise not operates by reversing all the bits in the operand.

You Might Also Like