Good idiom for filtering elements of an object (javascript)

I would like to remove certain elements of the object (for the sake of argument, those whose keys begin with '_'). What an elegant way to do this? Naive way:

for (var i in obj) if (i[0] === '_') delete obj[i]; 

but this changes the underlying object during the iteration. In Node, at least I think I could

 Object.keys(obj).forEach(function (i) { if (i[0] === '_') delete obj[i]; }); 

or restart the iteration every time something is deleted with an inconvenient nested loop.

Are there any better solutions?

EDIT: When testing just now, in node.js, at least the naive solution actually works. Of course, it is possible that for ... in (necessary) it is implemented safely. Somebody knows?

+6
source share
4 answers

You do not need to worry about it. Excerpt from ECMAScript Language Specification ยง12.6.4 explicitly indicates (emphasized by me):

The mechanics and order of listing properties (step 6.a in the first algorithm, step 7.a in the second) is not specified. The properties of an enumerated object can be deleted during enumeration. If a property that has not yet been visited during the enumeration is deleted, then it will not be visited. If new properties are added to the object that is being enumerated during the enumeration, newly added properties are not guaranteed to be visited in the active enumeration. The property name should not be visited more than once in any listing.

+17
source

why not create a list of names to delete for example

 var l = []; for (var i in obj) if (i[0] === '_') l.push(i); l.forEach(function(v){ delete obj[v]; }); 
+4
source
 Object.keys(obj).filter(function (v) { return v[0] === "_"; }).forEach(function (v) { delete obj[v]; }); 

This will change the object during the loop, p

If you use this more than once, the common is:

 Object.keys(obj).filter(function (v) { //filter the object values/keys by some conditions }).forEach( del.bind(obj) ); function del (v) { delete this[v]; } 
+4
source

An alternative is to create a function that returns a filtered object. I would prefer this solution to avoid side effects on other parts of the code that contain a link to a mutable object.

 function filterObject(obj) { var filtered = new Object(); for (var i in obj) if (i[0] != '_') filtered[i] = obj[i]; return filtered; } 
+2
source

Source: https://habr.com/ru/post/905456/


All Articles