Javascript 使用数组映射以 if 条件过滤结果

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26716818/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-22 23:16:26  来源:igfitidea点击:

Using array map to filter results with if conditional

javascriptangularjsmap

提问by ajmajmajma

I am trying to use an array map to filter a object a bit further to prepare it to send to the server to for saving. I can filter to 1 key value, which is great, but I want to take it 1 step further and check them against a boolean inside.

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

So, right now this is what I have -

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

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

This works great for pulling out the id's, however I don't want to push them in this new array if they their selected value == false, so I put a conditional to filter further. This somewhat works, I get an array of id's, but the id's that have .selected == false are still in the array, just with the value of null. So If I have 4 items in the object and 2 of them are false it looks like this -

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

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

My question is - is there a way to do this without the nulls being put in there. Thanks for reading!

我的问题是 - 有没有办法做到这一点,而无需将空值放入其中。谢谢阅读!

回答by Pointy

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

您正在寻找.filter()功能:

  $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).

这将生成一个数组,其中仅包含“selected”属性为true(或为真)的那些对象。

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

编辑抱歉,我正在喝咖啡,但我错过了评论 - 是的,正如 jAndy 在评论中指出的那样,过滤然后只提取“id”值,它会是:

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

一些函数式库(比如Functional,在我看来它并没有得到足够的喜爱)有一个.pluck()从对象列表中提取属性值的函数,但是原生 JavaScript 有一组非常精简的这样的工具。

回答by Justin L.

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

你应该使用Array.prototype.reduce来做到这一点。我确实做了一些 JS性能测试来验证这比执行.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 .reduceI used in the JSPerf test:

为了清楚起见,这里是.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)



EDIT 1

编辑 1

Note, As of 2/2018 Reduce + Pushis fastest in Chrome and Edge, but slower than Filter + Mapin Firefox

注意,截至 2/2018,Reduce + Push在 Chrome 和 Edge 中最快,但比Firefox 中的Filter + Map

回答by Laurynas

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

如果有人在 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.

我认为 reduce vs map + filter 可能在某种程度上取决于您需要循环的内容。对此不确定,但 reduce 似乎确实更慢。

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

这里是一个 JS 性能测试,它显示了在完全输入代码而不是检查“falsey”值(例如if (string) {...})或返回“falsey”值时的巨大改进,其中需要布尔值。

Hope this helps someone

希望这有助于某人