给出这样的多维数组:
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
}
问题是,如果我尝试使用计数器(用于递增的变量)而不是用于存储值的数组,则会得到错误的结果(在这种情况下,console.log(countItems(arr, "apple"));
而不是7,我得到了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
}
答案 0 :(得分:2)
您可以对数组采取递归方法,也可以检查该值并添加布尔值的结果。
function count(array, value) {
return array.reduce((s, a) => s + (Array.isArray(a) ? count(a, value) : a === value), 0);
}
var array = ["apple", ["banana", "strawberry", "dsffsd", "apple"], "banana", ["sdfdsf", "apple", ["apple", ["nonapple", "apple", ["apple"]]]], "apple"];
console.log(count(array, 'apple'));
带有for
循环的版本。
function count(array, value) {
var i,
sum = 0;
for (i = 0; i < array.length; i++) {
if (Array.isArray(array[i])) {
sum += count(array[i], value);
continue;
}
sum += array[i] === value;
}
return sum;
}
var array = ["apple", ["banana", "strawberry", "dsffsd", "apple"], "banana", ["sdfdsf", "apple", ["apple", ["nonapple", "apple", ["apple"]]]], "apple"];
console.log(count(array, 'apple'));
答案 1 :(得分:2)
我认为,如果您继续返回计数值并在计算中使用它,那么您将可以获得没有外部变量的最终数字:
function countItems(arr, item) {
let totc = 0; // totc is now local
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){ totc += countItems(arr[i], item) } // recursion, using the return value
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
}
}
请注意,我所做的唯一更改是在函数内部实例化了totc并获取了递归调用的结果并将其添加到本地总数中。
尼娜的答案更为优雅,但这也许会更容易理解。
答案 2 :(得分:1)
您可以使用arr.toString().split(",")
迭代arr的平面版本,因此不需要递归。
var arr = [
"apple",
["banana", "strawberry","dsffsd", "apple"],
"banana",
["sdfdsf","apple",["apple",["nonapple", "apple",["apple"]]]]
,"apple"];
var counts = {};
arr.toString().split(",").forEach(e=>{
counts[e] = (counts[e] || 0) +1
})
console.log(counts.apple)
如果元素内部包含“,”,则不能使用,而是可以使用。flat()而不是.toString().split(",")
答案 3 :(得分:1)
我认为这是一种简单的方法,但是您可以纠结于此:
function countItems(arr, item, count = 0){
if(!arr.length) return count; //if the array is empty then there's nothing else to count
let cTemp;
if(Array.isArray(arr[0])){ //if the next item is an array
cTemp = countItems(arr[0], item); //count the items in that array
} else {
cTemp = arr[0] === item ? 1 : 0; //if it's a string the compare it with item
//1 if we found it
//0 if we didn't
}
return countItems(arr.slice(1), item, count+cTemp);
//count the items of the rest of the array and add what we found
//arr.slice(1) is the rest of the array
//cTemp is the count for the first item in the array
}
当然可以重写为一行:
let countItems = ([first, ...rest], item, count = 0) => !first ? count : countItems(rest, item, count + (Array.isArray(first) ? countItems(first, item) : +(first === item)))
答案 4 :(得分:0)
function numberOfItems(arr, item) {
// Write the code that goes here
let count = 0
arr.forEach(element => {
if(item === element) {
count = count + 1;
}
if(Array.isArray(element)){
count += numberOfItems(element,item);
}
});
return count;
}