使用reduce方法查找数组中某个元素出现的次数。该数组可能包含递归的子数组。
var foo = [
1,
[2, 3, 4],
4, [5,6,7], 4
];
bar(foo, 4)
would return 3.
var foo = [
1,
[2, 3, 4],
4, [5,6,7], 4
];
bar(foo, 4)
would return 3.
使用Array.prototype.forEach()
方法,您可以通过一次调用计算所有项目。
forEach()
方法会为数组中的每个元素执行一次提供的函数。
And a check if the element is an array, then the function is called again with the array as parameter.
var foo = ["a", ["b", "c", "d"], "a"],
object = {};
function count(a, o) {
a.forEach(function (b) {
if (Array.isArray(b)) {
count(b, o);
} else {
o[b] = (o[b] || 0) + 1;
}
})
}
count(foo, object);
document.write('<pre>' + JSON.stringify(object, 0, 4) + '</pre>');
count
函数的内部 count
;这不就是递归的定义吗? - Dave Newton:)
- frogattoArray.prototype.reduce
来实现。
var foo = [1, [2, 3, 4], 4, [5, 6, 7], 4];
function f(arr, item) {
return arr.reduce(function (s, i) {
if (Array.isArray(i)) return s+f(i, item);
return s+(i==item?1:0);
}, 0);
}
console.log(f(foo, 4))
函数f
是一个递归函数。我们循环遍历所有项并将它们缩减为一个数字。该函数也会在所有内部数组上被调用,对于非数组项,我们只需检查它们是否等于所需项。
s
将被初始化为初始值(0),然后它将调用函数并将返回值再次存储到 s
中,并在下一个元素上调用该函数。这就是 reduce
的工作原理。 - Aᴍɪʀa=["One","Two","Tree"]
比较 a.reduce((t,v)=>t+v.length)
和 a.reduce((t,v)=>t+v.length,0)
(使用函数调用的紧凑形式)。 - edc65这里还有一种功能型的解释方式,不需要外部状态,但效率会更低。
var foo = [
"a",
["b", "c", "d"],
["a", "b"],
"a"
];
function flatten( arr ){
return arr.reduce(function( ret, curr ){
return ret.concat( Array.isArray( curr ) ? flatten( curr ) : [ curr ] );
}, []);
}
function filterBy( arr, val ){
return arr.filter(function( item ){
return item === val;
})
}
console.log( flatten( foo ) );
console.log( filterBy( flatten( foo ), 'a') );
<script src="http://codepen.io/synthet1c/pen/WrQapG.js"></script>
var foo = [
"a",
["b", "c", "d"],
"a"
];
function bar(arr, item) {
var count = 0;
if (arr.length == 0) {
return 0;
}
for (var i = 0, l = arr.length; i < l; i++) {
var v = arr[i];
if (typeof v === "string") {
if (v === item) {
count++;
}
} else {
count = count + bar(v, item);
}
}
return count;
}
console.log(bar(foo, "a"));
使用underscore,您可以使用以下代码计算每个元素出现的次数:
_.countBy(_.flatten(array), _.identity)
function bar(foo, element){
return _.countBy(_.flatten(foo), _.identity)[element];
}
var foo = ["a", ["b", "c", "d"], "a"]
console.log(bar(foo, "a"));
虽然这个解决方案不是递归的,但我认为值得一提。
bar(foo, "a")
会返回3
,尽管它的输入中只出现了两次"a"
呢? - Codor