JavaScript中reduce方法统计数组的异常行为求解释
数组reduce统计异常问题解析
嘿,我来帮你捋清楚这个问题的根源!
你遇到的问题核心是嵌套数组的隐式类型转换,咱们一步步拆解:
问题出在哪?
看你的otherAnimals数组,第三个元素是['cat', 'cat']——这是一个数组,不是字符串'cat'。当你用item in allItems判断时,JavaScript会自动把数组类型的item转换成字符串:
['cat', 'cat'].toString()的结果是"cat,cat",这和你之前的键'cat'完全是两回事- 所以代码会把这个嵌套数组当成一个全新的键,新增
"cat,cat": 1,而不会把数组里的两个'cat'单独统计进去
至于第一个animals数组返回{cat: 3, ...},其实是巧合:里面的['cat']转成字符串刚好是"cat",和原有的字符串'cat'键一致,所以被统计到了一起,但这只是碰巧,逻辑本身是有漏洞的。
怎么解决?
要实现你预期的统计结果,得先把多维数组扁平化(把嵌套的数组拆成一维数组),再进行统计。这里有两种常用方法:
方法1:使用ES6的flat()方法
flat(Infinity)可以处理任意深度的嵌套数组,修改后的代码如下:
var animals = ['cat', 'cat', ['cat'], 'dog', 'frog']; var otherAnimals = ['cat', 'cat', ['cat', 'cat'], 'dog', 'frog']; function reducingArrays(arraySource) { // 先扁平化数组,处理所有嵌套情况 const flattenedArray = arraySource.flat(Infinity); var countedData = flattenedArray.reduce(function(allItems, item) { if (item in allItems) { allItems[item]++; } else { allItems[item] = 1; } return allItems; }, {}); console.log(countedData); } reducingArrays(animals); // {cat: 3, dog: 1, frog: 1} reducingArrays(otherAnimals); // {cat: 4, dog: 1, frog: 1}
方法2:手动写递归扁平化函数(兼容旧环境)
如果需要兼容不支持flat()的旧浏览器,可以自己写一个递归函数来扁平化数组:
function flattenArray(arr) { let result = []; arr.forEach(item => { if (Array.isArray(item)) { result = result.concat(flattenArray(item)); } else { result.push(item); } }); return result; } // 然后在reducingArrays里替换成: const flattenedArray = flattenArray(arraySource);
这样处理后,不管数组嵌套多少层,里面的元素都会被拆出来统一统计,就能得到你想要的结果啦!
内容的提问来源于stack exchange,提问作者didaquis
相关产品推荐
相关产品推荐

