Marko Marko - 23 days ago 5
Javascript Question

Splice NOT removing certain characters

I'm working on some codewars problems and I came to this 'remove noise thing', I guess the point is to escape backslash \ and use replace method, which was easy. But I didn't want to use replace, instead I found myself in trouble trying to remove items with splice method.

Funny thing is, when I debug in Chrome dev tools, step by step I see items get removed, but console.log spits out certain characters($/·|ªl) problematic to remove, and at the end gets returned and join with those characters. Why is that?



function removeNoise(str) {
var base = "%$&/#·@|º\ª";
var arr = str.split('');

for(var i = 0; i < arr.length; i++) {
var item = arr[i];
var condition = base.indexOf(item);
if(condition + 1) {
//works like a charm
//arr[i] = '';

arr.splice(i,1);
//this thing wont work
//when debugging it removes the items from the array
//console log print no removing
}
}
return arr.join('');
}

removeNoise('he%$&/#·@|º\ª\llo'); //=> $/·|ªllo




Answer

You're using splice to remove entries from your array, but you're then incrementing i for the next loop. If you remove the entry at index 5 from a 10-entry array, what was the entry at index 6 is now at index 5 (of what's now a 9-entry array), so you don't want to increment your index.

The solution is to use a while loop and only update i if you don't splice:

function removeNoise(str) {
  var base = "%$&/#·@|º\ª";
  var arr = str.split('');

  var i = 0;
  while (i < arr.length) {
    var item = arr[i];
    var condition = base.indexOf(item);
    if (condition + 1) {
      // Remove this entry, reuse same value for 'i'
      arr.splice(i,1); 
    } else {
      // Don't remove this entry, move to next
      ++i;
    }
  }
  return arr.join(''); 
}

var result = removeNoise('he%$&/#·@|º\ª\llo');
var pre = document.createElement('pre');
pre.appendChild(
  document.createTextNode(result)
);
document.body.appendChild(pre);