过滤数组并创建新数组
2017-06-19
106
我有一个非常简单的需求,即从较大的数组中筛选一些对象并创建一个子数组。目前,我正在按如下方式执行,但我想知道我是否可以内联执行并避免 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个回答
由于您既想过滤数组又想修改保留的项目,因此可以将
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;
}, []);
Lennholm
2017-06-19
我认为您使用
forEach
并没有什么大问题,但您可以用对已筛选集执行
map
操作来替换它。
就我个人而言,我会使用
reduce
在一个循环中结合
filter
和
map
操作,但您可能只会在筛选非常大的数据集时才会开始看到性能提升。
要将两者结合在一个 Reducer 中:
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, []);
user3297291
2017-06-19