let names = ['Rachel', '', 'Meghana', '', '', 'Tim']
function deleteBlankItems(items) {
for (let i = 0; i < items.length; i++) {
if (items[i].length === 0) {
items.splice(i, 1);
}
}
return items;
}
I would think this code should eliminate all empty spaces in the array. But for some reason it doesn't delete this second empty array slot, and so the final array is ['Rachel', 'Meghana', '', 'Tim'] Why?
On each cycle of the for-loop the original array length is modified. With the splice() function the length of the array is modified and the index of each item is recalculated. That is, after the first empty string is removed, all the followings items' keys are rearrenged, and so on each time you remove an item.
For example:
In let names = ['Rachel', '', 'Meghana']; the second empty string has index 1 and 'Megana' has index 2. When the empty string is removed, the new array becomes ['Rachel', 'Meghana'];, where the string 'Meghana' takes index 1.
So, when in the for-loop, an item is removed from the array, the next items indexes are decreased by 1 while the iterator variable i is augmented of one (i++).
In your example, on the first iteration, i = 0, 'Rachel' is on index 0 and is not removed.
On the second iteration i = 1, '' (empty string) is on index 1 and gets removed; now 'Meghana' is on index 1, '' is on index 2, etc.
On the third iteration i = 2, '' is on index 2 (that's why 'Meghana' is skipped) and is removed; now the next '' is on index 2.
And so on with the other iterations.
I hope that what happens in the for-loop is clearer.
Using filter (as suggested in other answers) is surely the best practice now, since its implementation does not alter the original array but returns a new one.
Anyway, only for sake of information, you could also decrease the i variable by 1 when the item is removed.
Possible example:
let names = ['Rachel', '', 'Meghana', '', '', 'Tim'];
function deleteBlankItems(items) {
for (let i = 0; i < items.length; i++) {
if (items[i].length === 0) {
items.splice(i, 1);
i -= 1;
}
}
return items;
}
Since you are modifying the array. For this case, you can just use the filter function.
items.splice(i, 1); will modify the size of the actual array.
let names = ['Rachel', '', 'Meghana', '', '', 'Tim']
function compact(items) {
return items.filter((item) => Boolean(item));
}
console.log(compact(names));
// short version
const compact2 = (items) => items.filter(Boolean);
console.log(compact2(names));
As stated in the other comments, this is occurring because you are modifying the current array in place and continuing to iterate over the modified array. To fix this, you can use the filter method:
var names = ['Rachel', '', 'Meghana', '', '', 'Tim'];
console.log("Original Array: ", names);
names = names.filter(function (name) {
return name.length;
});
console.log("New Array: ", names);