I would like to check if an element inside an array is another array. I'm solving a code challenge where the problem is iterating through an array and checking for a 7 but if an element is an array I would like to continuously check each nested array for a 7.
I have console.log() in my first 'if' statement and I've seen that sevenBoom() is being called more than once. But for some reason it's not returning 'Boom!'
SevenBoom should return 'Boom!' if there's a seven.
function sevenBoom(arr) {
if (arr.includes(7)) {
return "Boom!";
}
arr.forEach((val) => {
if (Array.isArray(val)) sevenBoom(val);
});
}
sevenBoom([1, 3, 4, 6, [7]) // Returns undefined
sevenBoom([3, 7, 8, 9]) // Returns 'Boom!'
CodePudding user response:
const sevenBoom = (arr) => {
const recurse = (arr) => arr.some(n => Array.isArray(n) ? recurse(n) : n === 7);
if (recurse(arr)) {
return 'Boom';
}
}
This is assuming what should be returned other than 'Boom' is void
. It's a bit of an awkward place for recursion since you want to return a string if you meet some criteria and nothing otherwise.
CodePudding user response:
Firstly you need to return the value from your second if condition too.
But forEach()
cannot be interrupted (for ex: with a return statement) and will run for all items. So you can keep track using a flag variable outside the forEach()
and return your result on that basis.
function sevenBoom(arr) {
if (arr.includes(7)) {
return "Boom!";
}
let found = false;
arr.forEach((val) => {
if (Array.isArray(val)) if(sevenBoom(val)) found="Boom!";
})
return found;
}
console.log(sevenBoom([1,2,3]));
console.log(sevenBoom([1,2,7]));
console.log(sevenBoom([1,2,[2,7]]));
console.log(sevenBoom([1,2,[2,3,[4,5]]]));
console.log(sevenBoom([1,2,[2,3,[4,7]]]));
Note: How sevenBoom()
can be directly used inside an if statement. This is because of the concept of truthy and falsy values.
PS: As mentioned above, forEach()
will run for all items, no matter what. You can use any other looping mechanism like a simple for loop
, some()
etc. I just copied your code and hence used forEach()
CodePudding user response:
You could take a boolean value as result and use Array#some
for checking arrays.
function hasSeven(array) {
function seven(a) {
return a.includes(7) || a.some(v => Array.isArray(v) && seven(v));
}
return seven(array)
? 'Boom!'
: 'There is no 7';
}
console.log(hasSeven([7]));
console.log(hasSeven([[7]]));
console.log(hasSeven([[[7]]]));
console.log(hasSeven([]));
console.log(hasSeven([[]]));
console.log(hasSeven([[[]]]));
CodePudding user response:
I would check if an element is seven in the same loop that you are checking if an element is an array that way you can avoid going through the array unnecessarily.
const sevenBoom = arr => {
for (const ele of arr) {
if (ele === 7) return 'Boom';
if (Array.isArray(ele)) {
//this prevents you from halting your function early
//you only want to return in the loop if a 7 is found
if (boom(ele) === 'Boom') return 'boom'
}
}
}
CodePudding user response:
If 7 is not present in the root array, then your function isn't returning anything. Try this, just a minor refactoring:
function sevenBoom(arr) {
if (arr.includes(7)) return 'Boom!';
for(let val of arr) {
if (Array.isArray(val)) return sevenBoom(val);
}
}