JavaScript中的布尔数组掩码

7

作为一名Python和Numpy的开发者,我经常使用的一个特性是布尔掩码。

这里提供一个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

通常情况下,当使用另一个与其大小相同的数组对np.array进行索引时,将返回一个新数组,其中包含掩码数组值为真的那些索引处的元素。

在JavaScript中,我可以使用Array.prototype.mapArray.prototype.filter实现类似的功能,但代码更冗长,而且我的掩码会被破坏。

-> 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

在javascript中,是否有更好的方法来应用数组掩码,还是我必须每次复制掩码并使用filtermap


map 创建一个新的数组,不会破坏原始数组。 - RobG
.unshift()可以实现这个功能 - 否则我需要一个掩码条目的索引。 - Zev Isert
传递给 filter 的函数需要接受 3 个参数:值、索引和原始对象。所以这就是你的索引。或者编写自己的扩展,例如 Array.prototype.maskFilter,它只需要接受索引即可。 - RobG
不错 - 不知道有额外的参数。不用说,我仍然需要使用 mapfilter,对吧? - Zev Isert
1
是的,我想你得为numpy写一个等价物。我不熟悉它,但我认为这里有足够的信息来解决问题。还有reduce,它甚至更加灵活。 - RobG
1个回答

10

filtermap都会创建新的数组,所以它们没问题。但是,您使用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);

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

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 


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接