Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Boolean array masks in Javascript

Coming from Python and Numpy, a typical feature I find myself using frequently are boolean masks.

Here's an example in Python:

>>> mylist = np.array([50, 12, 100, -5, 73])
>>> mylist == 12
array([False, True, False, False, False])  # A new array that is the result of ..
                                           # .. comparing each element to 12
>>> mylist > 0
array([True, True, True, False, True])     # A new array that is the result of ..
                                           # .. comparing each element to 0
>>> mylist[mylist == 12]
array([12])                                # A new array of all values at indexes ..
                                           # .. where the result of `mylist == 12` is True

>>> mask = mylist != 100                   # Save a mask
>>> map(foo, mylist[mask])                 # Apply `foo` where the mask is truthy

In general when np.array is indexed by another array of the same size, a new array is returned containing the elements at those indexes where the mask array's value is truthy.

I am able to do something similar with Array.prototype.map and Array.prototype.filter in Javascript but it's more verbose and my mask is destroyed.

-> mylist = [50, 12, 100, -5, 73]
-> mylist.map(item => item == 12)
<- [false, true, false, false, false]      // mylist == 12

-> mylist.filter(item => item == 12)
<- [12]                                    // mylist[mylist == 12]

-> mask = mylist.map(item => item == 12)
-> mylist.filter(item => mask.unshift())
<- [12]                                    // mylist[mask]

-> mask
<- []                                      // Mask isn't reusable

Is there a better way of applying masks over arrays in javascript or am I stuck making copies of masks and using filter and map each time?

like image 865
Zev Isert Avatar asked Aug 10 '17 05:08

Zev Isert


People also ask

What are boolean masks?

Boolean masking, also called boolean indexing, is a feature in Python NumPy that allows for the filtering of values in numpy arrays.

What is mask in array?

A masked array is the combination of a standard numpy. ndarray and a mask. A mask is either nomask , indicating that no value of the associated array is invalid, or an array of booleans that determines for each element of the associated array whether the value is valid or not.

How do you find the true value of an array?

To count the true values in an array:Use the filter() method to iterate over the array. Check if each value is equal to true and return the result. Access the length property on the array to get the count of the true values.


Video Answer


1 Answers

Both filter and map create new arrays so they're fine. However, your use of unshift seems to be because you want the index rather than the value. You could pass the index in the call:

var mylist = [50, 12, 100, -5, 73];
var mask = mylist.map(item => item == 12);
var newlist = mylist.filter((item, i) => mask[i]);

console.log(newlist);

or if you don't want to pass more then one value, you could write your own maskFilter method of Array.prototype that takes just a mask instead:

Array.prototype.maskFilter = function(mask) {
  return this.filter((item, i) => mask[i]);
}

var mylist = [50, 12, 100, -5, 73];
var mask = mylist.map(item => item == 12);
var newlist = mylist.maskFilter(mask);


console.log(newlist); // [12]
console.log(mylist);  // untouched 
like image 104
RobG Avatar answered Nov 13 '22 23:11

RobG