使用数组映射来过滤if条件的结果

ajm*_*jma 36 javascript map angularjs

我正在尝试使用数组映射来进一步过滤对象,以准备将其发送到服务器以进行保存.我可以过滤到1个键值,这很好,但是我想进一步检查它们并根据布尔值检查它们.

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

$scope.appIds = $scope.applicationsHere.map( function(obj){
        if(obj.selected == true){
            return obj.id;
        }
    });
Run Code Online (Sandbox Code Playgroud)

这对于拉出id非常有用,但是如果他们选择的值== false,我不想在这个新数组中推送它们,所以我放了一个条件来进一步过滤.这有点工作,我得到一个id的数组,但是具有.selected == false的id仍然在数组中,只是值为null.所以,如果我在对象中有4个项目,其中2个是假的,它看起来像这样 -

 appIds = {id1, id2, null, null};
Run Code Online (Sandbox Code Playgroud)

我的问题是 - 有没有办法在没有空值的情况下执行此操作.谢谢阅读!

Poi*_*nty 76

你正在寻找这个.filter()功能:

  $scope.appIds = $scope.applicationsHere.filter(function(obj) {
    return obj.selected;
  });
Run Code Online (Sandbox Code Playgroud)

这将生成一个数组,其中只包含那些"selected"属性为true(或truthy)的对象.

编辑对不起,我得到了一些咖啡,我错过了评论 - 是的,正如jAndy在评论中指出的那样,过滤然后拔出"id"值,它是:

  $scope.appIds = $scope.applicationsHere.filter(function(obj) {
    return obj.selected;
  }).map(function(obj) { return obj.id; });
Run Code Online (Sandbox Code Playgroud)

一些功能库(比如功能,在我看来并没有得到足够的爱)有一个.pluck()从对象列表中提取属性值的功能,但是原生JavaScript有一套相当精简的工具.

  • @ user3201696你需要在过滤器之后链接一个`.map()`,绝对可以. (2认同)
  • @ user3201696它几乎看起来像`.filter(function(obj){return obj.selected;}).map(function(obj){return obj.id1});`那会创建一个只包含`id1`属性的值. (2认同)

Han*_*ans 22

您可以使用flatMap。它可以将过滤和映射合二为一。

$scope.appIds = $scope.applicationsHere.flatMap(obj => obj.selected ? obj.id : [])
Run Code Online (Sandbox Code Playgroud)


Jus*_* L. 12

您应该使用Array.prototype.reduce来执行此操作.我做了一点JS perf测试来验证这比执行.filter+ 更高效.map.

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

为了清楚起见,这是.reduce我在JSPerf测试中使用的示例:

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


编辑1

注意,自2/2018起,Reduce + Push在Chrome和Edge中速度最快,但在Firefox中比Filter + Map

  • @DanMandel - 过滤器 + 映射怎么可能是 O(n^2) ?我认为这将是 O(2n),基本上是 O(n) (2认同)
  • @DanMandel过滤器+映射绝对是O(n)而不是n²。 (2认同)

San*_*isy 8

简单的解决方案

SomeArrayValues.filter(x=> x.id !== idNameDetailsColorDto.id).map(ids => (ids.id))
Run Code Online (Sandbox Code Playgroud)