使用数组映射用 if 条件筛选结果

我正在尝试使用一个数组映射来过滤一个对象稍微进一步准备它发送到服务器保存。我可以过滤到1个键值,这很棒,但我想更进一步,并检查他们对布尔值内。

所以,现在这就是我所拥有的

$scope.appIds = $scope.applicationsHere.map( function(obj){
if(obj.selected == true){
return obj.id;
}
});

这对于提取 id 非常有用,但是如果它们的选择值 = = false,我不想将它们放入这个新数组中,所以我放了一个条件来进一步筛选。这有点用,我得到一个 id 的数组,但是这个 id 有。Select = = false 仍然在数组中,只是值为 null。所以如果对象中有4个条目,其中2个是假的,看起来像这样-

 appIds = {id1, id2, null, null};

我的问题是,有没有办法不把空值放进去。感谢您的阅读!

233137 次浏览

You're looking for the .filter() function:

  $scope.appIds = $scope.applicationsHere.filter(function(obj) {
return obj.selected;
});

That'll produce an array that contains only those objects whose "selected" property is true (or truthy).

edit sorry I was getting some coffee and I missed the comments - yes, as jAndy noted in a comment, to filter and then pluck out just the "id" values, it'd be:

  $scope.appIds = $scope.applicationsHere.filter(function(obj) {
return obj.selected;
}).map(function(obj) { return obj.id; });

Some functional libraries (like Functional, which in my opinion doesn't get enough love) have a .pluck() function to extract property values from a list of objects, but native JavaScript has a pretty lean set of such tools.

You should use Array.prototype.reduce to do this. I did do a little JS perf test to verify that this is more performant than doing a .filter + .map.

$scope.appIds = $scope.applicationsHere.reduce(function(ids, obj){
if(obj.selected === true){
ids.push(obj.id);
}
return ids;
}, []);

Just for the sake of clarity, here's the sample .reduce I used in the JSPerf test:

  var things = [
{id: 1, selected: true},
{id: 2, selected: true},
{id: 3, selected: true},
{id: 4, selected: true},
{id: 5, selected: false},
{id: 6, selected: true},
{id: 7, selected: false},
{id: 8, selected: true},
{id: 9, selected: false},
{id: 10, selected: true},
];
  

  	

var ids = things.reduce((ids, thing) => {
if (thing.selected) {
ids.push(thing.id);
}
return ids;
}, []);


console.log(ids)


EDIT 1

Note, As of 2/2018 Reduce + Push is fastest in Chrome and Edge, but slower than Filter + Map in Firefox

Here's some info if someone comes upon this in 2019.

I think reduce vs map + filter might be somewhat dependent on what you need to loop through. Not sure on this but reduce does seem to be slower.

One thing is for sure - if you're looking for performance improvements the way you write the code is extremely important!

Here a JS perf test that shows the massive improvements when typing out the code fully rather than checking for "falsey" values (e.g. if (string) {...}) or returning "falsey" values where a boolean is expected.

Hope this helps someone

You could use flatMap. It can filter and map in one.

$scope.appIds = $scope.applicationsHere.flatMap(obj => obj.selected ? obj.id : [])

Simple solution

SomeArrayValues.filter(x=> x.id !== idNameDetailsColorDto.id).map(ids => (ids.id))