Reputation: 1556
I need to delete a subarray if it has a particular element.
function filteredArray(arr, elem) {
let newArr = [];
for (let i = 0; i < arr.length; i++){
for (let j = 0; j < arr[i].length; j++) {
if (arr[i][j] === elem) {
arr.splice(i--, 1);
newArr = [...arr]
}
}
}
return newArr;
}
console.log(filteredArray([[3, 2, 3], [1, 6, 3], [3, 13, 26], [19, 3, 9]], 19));
The code above works fine if the element is found just once (for ex. 19). But if I try number 3, I get: Uncaught TypeError: Cannot read property 'length' of undefined
. Can someone please explain what is happening here?
Upvotes: 1
Views: 1260
Reputation: 56905
The issue is that once you've splice
d an item out of the array, your program continues iterating over the rest of the removed inner array as if it still existed. In the case of 3
as your target, every single inner array is removed because they all contain a 3
. At the final removal, you detect a 3
at index 1
of the inner array and splice
the last inner array. On the next iteration of the loop, the program crashes attempting to index into [0][2]
in the empty array []
.
The solution is to add a break
statement as follows; this will abort further inspection of a removed array:
function filteredArray(arr, elem) {
let newArr = [];
for (let i = 0; i < arr.length; i++){
for (let j = 0; j < arr[i].length; j++) {
if (arr[i][j] === elem) {
arr.splice(i--, 1);
newArr = [...arr]
break;
}
}
}
return newArr;
}
console.log(filteredArray([[3, 2, 3], [1, 6, 3], [3, 13, 26], [19, 3, 9]], 3));
Having said that, there are many simpler approaches you can take; for example, using array.filter()
, which selects elements based on the truth value returned by its argument function:
const filteredArray = (a, target) => a.filter(e => !e.includes(target));
console.log(filteredArray([[3, 2, 3], [1, 6, 3], [3, 13, 26], [19, 3, 9]], 3));
console.log(filteredArray([[3, 2, 3], [1, 6, 3], [3, 13, 26], [19, 3, 9]], 19));
Upvotes: 1
Reputation: 92440
Using filter()
with includes()
is succinct enough you probably don't need a separate function:
let array = [[3, 2, 3], [1, 6, 3], [3, 13, 26], [19, 3, 9]]
let filtered = array.filter(item => !item.includes(19));
console.log(filtered)
Upvotes: 3
Reputation:
Try Array.filter()
function filteredArray(arr, skip) {
return arr.filter(function(sub) {
return -1 === sub.indexOf(skip);
});
}
var mixed = [[3, 2, 3], [1, 6, 2], [3, 13, 26], [19, 3, 9]];
console.log(filteredArray(mixed, 19));
console.log(filteredArray(mixed, 3));
Upvotes: 1