ZK Zhao
ZK Zhao

Reputation: 21573

javascript: Unable to delete some elements of an array

http://jsfiddle.net/83m3B/

I want to delete some elements of an array by using data-object-id attribute. But when I use it, the loop does not run as expected. It seems like it jumps over an element every time.

var banIds = ["111", "222", "333"];
function toggle_visibility(className) {
  var elements = document.getElementsByClassName(className),
    n = elements.length;
  for (var i = 0; i < n; i++) {
    var e = elements[i];
    var statusID = e.getAttribute('data-object-id');
    if ($.inArray(statusID, banIds) !== -1) {
      e.remove();
    }
  }
}

What's the problem? And how do I solve it ?

Upvotes: 0

Views: 70

Answers (3)

VitaliyG
VitaliyG

Reputation: 1857

This is typical error when deleting elements from indexed list.
You are missing fact that when element is deleted all elements after deleted are shifted in index to index-1. So the next element receives same index as deleted one but for loop still increments index and skips one element after deleted.
Simplest way to avoid this problem is to run loop backward:

  for (var i = n-1; i >= 0; i--) {
    var e = elements[i];
    var statusID = e.getAttribute('data-object-id');
    if ($.inArray(statusID, banIds) !== -1) {
      e.remove();
    }

Upvotes: 0

zerkms
zerkms

Reputation: 255005

As soon as jQuery is acceptable there is no reason to not use its facilities:

function toggle_visibility(className) {
    $('.' + className).filter(function() {
        return $.inArray($(this).data('object-id'), banIds) !== -1;
    }).remove();
}

Upvotes: 3

CnapoB
CnapoB

Reputation: 675

Use while cycle for delete. For cycle skips elements, because they already deleted and other elements have another position index in array.

Or write like this:

if ($.inArray(statusID, banIds) !== -1) {
    e.remove();
    i--;
}

And don't use n, because elements.length changes in cycle.

Upvotes: 2

Related Questions