Учитывая многомерный массив, подобный этому:
var arr = [
"apple",
["banana", "strawberry","dsffsd", "apple"],
"banana",
["sdfdsf","apple",["apple",["nonapple", "apple",["apple"]]]]
,"apple"];
Задача состояла в том, чтобы написать функцию, которая хранит массив и элемент в качестве аргументов и возвращает количество раз, когда этот элемент появляется в массиве.
Мое первое решение помогло:
function countItems(arr, item, sumarr = []) { // sumarr = array to store items matched
for (let i = 0; i < arr.length; i++ ){ // iterate on arr
let isarray = arr[i].constructor === Array // if the element is a nested array
if(isarray){ countItems(arr[i], item, sumarr) } // recursion
let isin = arr[i] === item; // ELSE if the item is in the arr
if(isin) { sumarr.push(arr[i])}; // add the element in the summ array
}
console.log(sumarr); // I preferred an array over a simple counter to be able to double check the result
return sumarr.length; // the length of the sum array show how many items founded
}
Проблема в том, что если я пытаюсь использовать счетчик (переменную для приращения) вместо массива для хранения значений, у меня будет неправильный результат (вместо 7 в данном случае console.log(countItems(arr, "apple"));
у меня 2). Если я правильно понял, это из-за функции рекурсии, которая вызывает замыкание, потому что, если я использую глобальную переменную, она работает.
Как этого добиться без глобальной переменной?
С глобальной переменной это так:
let totc = 0;
function countItems(arr, item) {
for (let i = 0; i < arr.length; i++ ){ // iterate on arr
let isarray = arr[i].constructor === Array; // if the element is a nested array
if(isarray){ countItems(arr[i], item) } // recursion
let isin = arr[i] === item; // ELSE if the item is in the arr
if(isin) { totc ++; };
}
return totc; // the length of the sum array show how many items founded
}