Boolean array masks in Javascript

Zev*_*ert 6 javascript arrays numpy

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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?

Rob*_*obG 10

这两个过滤器地图创建新的阵列,所以他们的罚款。但是,您使用unshift似乎是因为您想要索引而不是值。您可以在调用中传递索引:

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);
Run Code Online (Sandbox Code Playgroud)

或者,如果您不想传递多个值,您可以编写自己的 Array.prototype的maskFilter方法,该方法只需要一个掩码:

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 
Run Code Online (Sandbox Code Playgroud)