admin管理员组

文章数量:1410724

I have a case where I need to iterate through an array of objects, check a conditional on each element , delete existing object & add new object based on the oute of the conditional. The code I have currently is as below, but of course it doesn't work.

What is the right approach to iterate through an array while adding / deleting new elements on certain iterations.

var arrayOfObjects = [] // a list to store objects of the same time
for(var i = 0; i < 5; i++){
  arrayOfObjects.push(new someClass());
}

while(true){
  for(var obj in arrayOfObjects){
    // some conditional check on obj
    // if check is true, delete the obj from array & add a new object
    arrayOfObjects.splice(arrayOfObjects.indexOf(obj),1);
    arrayOfObjects.push(new someClass());    
  }
}

I have a case where I need to iterate through an array of objects, check a conditional on each element , delete existing object & add new object based on the oute of the conditional. The code I have currently is as below, but of course it doesn't work.

What is the right approach to iterate through an array while adding / deleting new elements on certain iterations.

var arrayOfObjects = [] // a list to store objects of the same time
for(var i = 0; i < 5; i++){
  arrayOfObjects.push(new someClass());
}

while(true){
  for(var obj in arrayOfObjects){
    // some conditional check on obj
    // if check is true, delete the obj from array & add a new object
    arrayOfObjects.splice(arrayOfObjects.indexOf(obj),1);
    arrayOfObjects.push(new someClass());    
  }
}
Share edited Nov 27, 2015 at 2:51 Alexander Elgin 6,9954 gold badges42 silver badges52 bronze badges asked Nov 27, 2015 at 1:35 user3206440user3206440 5,06916 gold badges84 silver badges138 bronze badges 7
  • so what seems to be the problem? – Tree Nguyen Commented Nov 27, 2015 at 1:37
  • Iterate the array and nest the object iteration within it,possibly – Keith Beard Commented Nov 27, 2015 at 1:40
  • 3 While true... Looks like an infinite to me. – Phix Commented Nov 27, 2015 at 1:40
  • 1 The OP says in first line it doesn't work. Then it is off-topic for Code Review. Please don't refer them to Code Review when the code is broken – holroy Commented Nov 27, 2015 at 1:44
  • Your main issue could be that with while(true) you'll keep on repeating the for loop, over and over again... There is no stopping or breaking out of the while loop – holroy Commented Nov 27, 2015 at 1:45
 |  Show 2 more ments

3 Answers 3

Reset to default 4

Modification of an object / array during iteration over it is an antipattern. Consequences are unpredictable. E.g. the loop is iterated over newly added items as well and it can happen that on every iteration a new item is added. Hence there is an infinite loop.

A better solution is to copy / add the items to a new empty object / array.

var result = [];
arrayOfObjects.forEach(function(obj) {
	if(isCopyRequired(obj)) {
		result.push(obj);
	}

	if(isNewObjectRequired(obj)) {
		result.push(new someClass());
	}
});

If you really need to add the new object to the end of the array

for(var obj = 0; obj < arrayOfObjects.length; obj += 1){
    var index;
    // some conditional check on obj
    // if check is true, delete the obj from array & add a new object
    if(somecondtion) {
        var index = arrayOfObjects.indexOf(obj);
        arrayOfObjects.splice(index, 1);
        arrayOfObjects.push(new someClass());    
        if (index <= obj) {
            obj -= 1;
        }
    }
}

if the removed item is in current position (obj) or earlier in the array, then subtract one from obj, which will effectively mean that the same position in the array will be checked the next iteration - which is what was the next element before the slice was done

The "correct" way to iterate over an Array is to use a for loop, since for..in iterates over all enumerable properties (own and inherited) and order is not guaranteed, so additional checks may be required. for..in is useful for sparse arrays, but they aren't mon.

There does not seem to be any rationale to removal of elements or their order in the array. All you need to do to remove them is to assign a reference to some other object to their index in the array, e.g.

while(true){

Do you really want this to loop forever? I think you should just remove the while block.

for (var i=0, iLen=arrayOfObjects.length; i<iLen; i++) {

  // some conditional check on obj
  // if check is true, delete the obj from array & add a new object
  if (check) {
    arrayOfObjects[i] = new someClass();    
  }
}

The main difference here is that your original code will add the new object at the end of the array, whereas this verison will add the new object at the same index as the old one.

You can also use forEach:

arrrayOfObjects.forEach(function(value, index) {

  // do check on value
  if (check) arrayOfObjects[i] = new someClass();
});

本文标签: JavaScriptaddremove elements of array of objects during iterationStack Overflow