0

I have a very simple requirement for filter some objects from a larger array and create a sub-array. Right now, I'm doing it as follows, but I'm wondering whether I could do inline and avoid the 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 });
        });
5
  • you do realise there's an in-built filter function? developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… Commented Jun 19, 2017 at 9:30
  • yes, the reason I'm creating a separate array is I only want an id-value pair in the second array. Commented Jun 19, 2017 at 9:31
  • then combine filter and map. And you need to provide more code, because from what you've given, it's too difficult to help Commented Jun 19, 2017 at 9:31
  • What is your filter criteria? What will be the input and expected output? Commented Jun 19, 2017 at 9:33
  • from the locations array, I need to filter out the locations with type=5, and then create a new array with only the Id and the displayname. the new array is branchList Commented Jun 19, 2017 at 9:35

2 Answers 2

2

Since you want to both filter the array and modify the retained items, you can use filter() in combination with map(), both native array methods

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

If you want to avoid iterating over the array twice you can use the reduce() method to perform both the filtering and mapping at the same time

vm.branchList = vm.locations
  .reduce(function(builtList, location) {
    if (location.fkLocationTypeId === 5) {
      return builtList.concat({
        id: location.Id,
        label: location.locationDisplayName
      });
    }
    return builtList;
  }, []);
Sign up to request clarification or add additional context in comments.

Comments

2

I don't think there's much wrong with your use of forEach, but you could replace it by a map operation on the filtered set.

Personally, I'd use reduce to combine both filter and map operations in one loop, but you'd probably only start seeing a performance increase when you're filtering very large sets of data.

To combine the two in one 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, []);
    

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.