过滤数组并创建一个新数组

时间:2017-06-19 09:29:37

标签: javascript arrays filter

我有一个非常简单的要求,即从较大的数组中过滤一些对象并创建一个子数组。现在,我正在按照以下方式进行,但我想知道我是否可以进行内联并避免使用for-each。

        var branches = $filter('filter')(vm.locations, { 'fkLocationTypeId': 5 });
        vm.branchList = [];
        angular.forEach(branches, function (obj) {
            vm.branchList.push({ id: obj.Id,  label: obj.locationDisplayName });
        });

2 个答案:

答案 0 :(得分:2)

由于您希望同时过滤数组并修改保留的项目,因此可以将filter()map()结合使用,两种原生数组方法

vm.branchList = vm.locations
  .filter(function(location) {
    return location.fkLocationTypeId === 5;
  })
  .map(function(location) {
    return {
      id: location.Id,
      label: location.locationDisplayName
    };
  });

如果您想避免迭代数组两次,可以使用reduce()方法同时执行过滤和映射

vm.branchList = vm.locations
  .reduce(function(builtList, location) {
    if (location.fkLocationTypeId === 5) {
      return builtList.concat({
        id: location.Id,
        label: location.locationDisplayName
      });
    }
    return builtList;
  }, []);

答案 1 :(得分:2)

我认为您使用forEach时没有太大问题,但您可以通过过滤后的map操作替换它。

就个人而言,我会使用reduce在一个循环中结合filtermap个操作,但是当你过滤时,你可能只会开始看到性能提升大量数据。

将两者合并为一个减速器:

const locToObj = loc => 
  ({ id: loc.Id,  label: loc.locationDisplayName });
 
const branchReducer = (acc, loc) =>
  loc.fkLocationTypeId === 5
    ? (acc.push(locToObj(loc)), acc)
    : acc
 
const branches = vm.locations.reduce(branchReducer, []);