我正在尝试使用数组映射来进一步过滤对象以准备将其发送到服务器以进行保存。我可以过滤到1个键值,这很好,但我想更进一步,并检查它们内部的布尔值。
所以,现在这就是我所拥有的 -
$scope.appIds = $scope.applicationsHere.map( function(obj){
if(obj.selected == true){
return obj.id;
}
});
这非常适合拔出id,但是如果他们选择的值== false,我不想在这个新数组中推送它们,所以我提出了一个条件来进一步过滤。这有点工作,我得到一个id的数组,但是具有.selected == false的id仍然在数组中,只是值为null。所以如果我在对象中有4个项目,其中2个是假的,它看起来像这样 -
appIds = {id1, id2, null, null};
我的问题是 - 有没有办法在没有空值的情况下执行此操作。谢谢你的阅读!
答案 0 :(得分:58)
您正在寻找.filter()
功能:
$scope.appIds = $scope.applicationsHere.filter(function(obj) {
return obj.selected;
});
这将生成一个数组,其中只包含那些“selected”属性为true
(或真实)的对象。
编辑抱歉,我得到了一些咖啡,我错过了评论 - 是的,正如jAndy在评论中指出的那样,过滤然后选择“id”值,它是:
$scope.appIds = $scope.applicationsHere.filter(function(obj) {
return obj.selected;
}).map(function(obj) { return obj.id; });
一些功能库(比如Functional,在我看来并没有得到足够的爱)有一个.pluck()
函数从对象列表中提取属性值,但原生JavaScript有一个非常精简一套这样的工具。
答案 1 :(得分:8)
您应该使用Array.prototype.reduce来执行此操作。我确实做了little JS perf test来验证这比执行[x y]=meshgrid(1:600)
+ .filter
更有效。
.map
为了清楚起见,这是我在JSPerf测试中使用的示例$scope.appIds = $scope.applicationsHere.reduce(function(ids, obj){
if(obj.selected === true){
ids.push(obj.id);
}
return ids;
}, []);
:
.reduce
编辑1
注意,自2/2018起, Reduce + Push 在Chrome和Edge中速度最快,但在Firefox中过滤器+地图
答案 2 :(得分:2)
您可以使用 flatMap。过滤和映射合二为一。
$scope.appIds = $scope.applicationsHere.flatMap(obj => obj.selected ? obj.id : [])
答案 3 :(得分:0)
如果有人在2019年遇到这个问题,这里有一些信息。
我认为reduce vs map + filter可能在某种程度上取决于您需要遍历的内容。不确定,但是减少似乎会更慢。
可以肯定的是-如果您正在寻求性能改进,那么编写代码的方式就非常重要!
Here a JS perf test显示了在完全键入代码而不是检查“假”值(例如if (string) {...}
)或返回期望布尔值的“假”值时的重大改进。
希望这对某人有帮助