user1486133
user1486133

Reputation: 1487

Remove current object by index inside _.each with underscore

I have a nested object like so:

var depositOptions = {
  0 : {name: 'Monthly'},
  1 : {name : 'Standard'},
  2 : {name: 'Full' },
  3 : {name: 'Low' }
};

I need to remove the object where name = 'Standard' so I'm iterating over it using Underscore.js _.each until I find it, and storing the index.

_.each(depositOptions, function(option, i) {
      if (option.name === 'Standard') {
        // delete the object at index i
        console.log(i)
      }
    });

So I want to remove the option when it finds standard - what is the easiest way to do this?

1) Remove it inside the _.each loop, when standard is found? (Therefore no need for the index) 2) Store the index of the object I want to remove, and then delete it after I've finished iterating? (This I am finding difficult because how do I get the index outside of the loop?) 3) Start creating a new array as I iterate over depositOptions so that a new array is built without standard included

When I say I want to delete it, I want it completely gone. So not just undefined like using delete does.

Upvotes: 1

Views: 810

Answers (5)

Xotic750
Xotic750

Reputation: 23482

You have 2 options, you either mutate your original object or you create a new object without the unwanted key-value pair. All examples are in plain ES6, but you can easily use lodash methods. They will exclude all matches not just the first match.

Mutation. Uses for..of and Object.keys

const depositOptions = {
  0: {
    name: 'Monthly'
  },
  1: {
    name: 'Standard'
  },
  2: {
    name: 'Full'
  },
  3: {
    name: 'Low'
  }
};
for (let key of Object.keys(depositOptions)) {
  if (depositOptions[key].name === 'Standard') {
    delete depositOptions[key];
  }
}
console.log(depositOptions);

Create new object without the reference to the unwanted object.

const depositOptions = {
  0: {
    name: 'Monthly'
  },
  1: {
    name: 'Standard'
  },
  2: {
    name: 'Full'
  },
  3: {
    name: 'Low'
  }
};
const depositOptionsFiltered = {};
for (let key of Object.keys(depositOptions)) {
  if (depositOptions[key].name !== 'Standard') {
    depositOptionsFiltered[key] = depositOptions[key];
  }
}
console.log(depositOptionsFiltered);

You may even want a new object and the key-value object to be a copy of the original rather than references to them. In this case you can perform a shallow copy. Uses Object.assign

const depositOptions = {
  0: {
    name: 'Monthly'
  },
  1: {
    name: 'Standard'
  },
  2: {
    name: 'Full'
  },
  3: {
    name: 'Low'
  }
};
const depositOptionsFiltered = {};
for (let key of Object.keys(depositOptions)) {
  if (depositOptions[key].name !== 'Standard') {
    depositOptionsFiltered[key] = Object.assign({}, depositOptions[key]);
  }
}
console.log(depositOptionsFiltered);

Upvotes: 0

Daniel A. White
Daniel A. White

Reputation: 190942

Use _.filter or _.reject instead. It wouldn't be clear to use _.each. Notice that these return a new array.

var newArray = _.filter(depositOptions, function(option) {
  return option.name !== 'Standard';
});

Also it looks like you have an object, not an array. Here is an array:

var depositOptions = [
  {name: 'Monthly'},
  {name : 'Standard'},
  {name: 'Full' },
  {name: 'Low' }
];

Upvotes: 2

Nikhil Nanjappa
Nikhil Nanjappa

Reputation: 6642

According to me the best way to do that using underscore is _reject.

Usage -

_.reject(depositOptions, function(val){ return val.name == 'Standard'; });

Option 3 is definitely not an option because you using exclusion method, where you are trying to fetch all other elements apart from the one you want & make use of the element you want. Too dirty for your implementation!

Option 2 is better than option 3 but not ideal because you have found the element & your still wasting your time iterating over others

Option 1 with a tweak is the best solution from the options given - small tweak includes add a break statement within the if statement & after you store the element. This way your just iterating till you find the element.

Upvotes: 0

Nenad Vracar
Nenad Vracar

Reputation: 122057

If you want to return new object with filtered properties you can use Object.keys() and reduce() in plain javascript.

var depositOptions = {
  0 : {name: 'Monthly'},
  1 : {name : 'Standard'},
  2 : {name: 'Full' },
  3 : {name: 'Low' }
};

var result = Object.keys(depositOptions).reduce(function(r, k) {
  if (depositOptions[k].name != 'Standard') r[k] = depositOptions[k]
  return r;
}, {})

console.log(result)

Upvotes: 1

David R
David R

Reputation: 15647

You can use the _.without function to eliminate the key which you don't need

var depositOptions = {
  0 : {name: 'Monthly'},
  1 : {name : 'Standard'},
  2 : {name: 'Full' },
  3 : {name: 'Low' }
};


depositOptions = _.without(depositOptions, _.findWhere(depositOptions, {
  name: 'Standard'
}));


console.log(depositOptions);

Hope this helps!.

Upvotes: 1

Related Questions