this the forth project from the odin project, all tests passed but the fifth one which required removing all elements failed and when i run the code it returns an array with half elements in original array before mutating.
**I don't know why IT DOESN'T RETURN AN EMPTY ARRAY. ** in the fifth test.
const removeFromArray = function (array, ...deleteElement) {
for (let i = 0; i < array.length; i ) {
if (array.includes(deleteElement[i])) {
array.splice(array.indexOf(deleteElement[i]), 1);
}
}
return array;
};
const randomArray = [1, 2, 3, 4];
console.log(removeFromArray(randomArray, 1, 2, 3, 4));
and this the test
const removeFromArray = require('./removeFromArray')
describe('removeFromArray', () => {
test('removes a single value', () => {
expect(removeFromArray([1, 2, 3, 4], 3)).toEqual([1, 2, 4]);
});
test('removes multiple values', () => {
expect(removeFromArray([1, 2, 3, 4], 3, 2)).toEqual([1, 4]);
});
test('ignores non present values', () => {
expect(removeFromArray([1, 2, 3, 4], 7, "tacos")).toEqual([1, 2, 3, 4]);
});
test('ignores non present values, but still works', () => {
expect(removeFromArray([1, 2, 3, 4], 7, 2)).toEqual([1, 3, 4]);
});
test.skip('can remove all values', () => {
expect(removeFromArray([1, 2, 3, 4], 1, 2, 3, 4)).toEqual([]);
});
test.skip('works with strings', () => {
expect(removeFromArray(["hey", 2, 3, "ho"], "hey", 3)).toEqual([2, "ho"]);
});
test.skip('only removes same type', () => {
expect(removeFromArray([1, 2, 3], "1", 3)).toEqual([1, 2]);
});
});
CodePudding user response:
In the for
you are looping trough the wrong element. It should be deleteElement.length
, not array.length
const removeFromArray = function(array, ...deleteElement) {
for (let i = 0; i < deleteElement.length; i ) {
if (array.includes(deleteElement[i])) {
array.splice(array.indexOf(deleteElement[i]), 1);
}
}
return array;
};
const randomArray = [1, 2, 3, 4];
console.log(removeFromArray(randomArray, 1, 2, 3, 4));
EDIT: although this will not work correctly when there are 2 same element to delete in the array. Here is another implementation which is deleting all matched indexes and not only the first one.
const removeFromArray = function(array, ...deleteElement) {
for (let i = 0; i < deleteElement.length; i ) {
let foundIndex = array.indexOf(deleteElement[i]);
while (foundIndex !== -1) {
array.splice(foundIndex, 1);
foundIndex = array.indexOf(deleteElement[i]);
}
}
return array;
};
const randomArray = [1, 2, 3, 1, 4];
console.log(removeFromArray(randomArray, 1));
CodePudding user response:
Your function iterates over the wrong variable (array.length
)
const removeFromArray = function (array, ...deleteElement) {
for (let element of deleteElement) {
if (array.includes(element)) {
array.splice(array.indexOf(element), 1);
}
}
return array;
};
CodePudding user response:
The problem is that the for loop is using the array.length
property dynamically, which means it is going to be evaluated every time you pass the loop, so since you are removing the elements from the original array, this value is not constant and at some point the array length value and the i
counter will get out of sync.
You just need to save the array length value in a variable so it stays the same after you remove the objects from the array.
var arrLen = array.length;
for (let i = 0; i < arrLen; i ) {
...
}
Update:
Pasting the full code here plus a live sample: https://jsfiddle.net/bcngr/sbk1yhmn/
const removeFromArray = function (array, ...deleteElement) {
var arrLen = array.length; // Save the length value before any modification to the array
for (let i = 0; i < arrLen; i ) { // use the variable instead of array.length
if (array.includes(deleteElement[i])) {
array.splice(array.indexOf(deleteElement[i]), 1);
}
}
return array;
};
const randomArray = [1, 2, 3, 4];
console.log(removeFromArray(randomArray, 1, 2, 3, 4));