Javascript中reduce方法的怪异行为

Javascript中reduce方法的怪异行为,javascript,arrays,Javascript,Arrays,有人能给我解释一下这种情况吗 在第二次调用函数时,结果是{cat:2,cat,cat:1,dog:1,frog:1} 然而,我认为结果将是{cat:4,dog:1,frog:1} 这是怎么回事 var-animals=['cat','cat',['cat','dog','frog']; 其他动物变量=[“猫”,“猫”,“猫”,“狗”,“青蛙]; 函数缩减阵列(arraySource){ var countedData=arraySource.reduce(函数(所有项,项){ 如果(所有项目中

有人能给我解释一下这种情况吗

在第二次调用函数时,结果是
{cat:2,cat,cat:1,dog:1,frog:1}

然而,我认为结果将是
{cat:4,dog:1,frog:1}

这是怎么回事

var-animals=['cat','cat',['cat','dog','frog'];
其他动物变量=[“猫”,“猫”,“猫”,“狗”,“青蛙];
函数缩减阵列(arraySource){
var countedData=arraySource.reduce(函数(所有项,项){
如果(所有项目中的项目){
所有项目[项目]+;
}否则{
所有项目[项目]=1;
}
返回allItems;
}, {});
console.log(countedData);
}
减少阵列(动物);//{猫:3,狗:1,青蛙:1}
减少阵列(其他动物);//{猫:2,猫,猫:1,狗:1,青蛙:1}

//我所期望的:{cat:4,dog:1,frog:1}
如果其中一个对象是数组,则必须处理:

function reducingArrays(arraySource){
    var countedData = arraySource.reduce(function (allItems, item) {
        var items = [item];
        if(item.constructor === Array){
            items = item;
        }
        items.forEach(function(item){
            if (item in allItems) {
                allItems[item]++;
            } else {
                allItems[item] = 1;
            }               
        });
        return allItems;
    }, {});
    console.log(countedData);
}

可以将单个元素转换为数组:

var-animals=['cat','cat',['cat','dog','frog'];
其他动物变量=[“猫”,“猫”,“猫”,“狗”,“青蛙];
函数缩减阵列(arraySource){
var countedData=arraySource.reduce(函数(所有项,项){
var arr=Array.isArray(项)?项:[项];
allItems[arr[0]=(allItems[arr[0]]||0)+arr.length;
返回allItems;
}, {});
console.log(countedData);
}
减少阵列(动物);

减少辐射(其他动物)
Yoh可以对数组进行检查,并对嵌套数组使用相同的
reduce
回调

函数缩减数组(arraySource){
返回arraySource.reduce(函数iter(所有项,项){
if(阵列isArray(项目)){
返回项目。减少(iter、allItems);
}
所有项目[项目]=(所有项目[项目]| | 0)+1;
返回allItems;
}, {});
}
动物变量=[‘猫’、[‘猫’]、‘狗’、‘青蛙’];
其他动物变量=[“猫”,“猫”,“猫”,“狗”,“青蛙];
console.log(减少数组(动物));//{猫:3,狗:1,青蛙:1}

console.log(减少阵列(其他动物));//{cat:4,dog:1,frog:1}
第一条注释已经解释过,这与数组的字符串化方式有关,因为对象键只能是字符串

这里介绍了如何在函数中处理嵌套数组

函数countAnimals(源代码){
功能_计数(所有项目、项目){
if(阵列isArray(项目)){
退货项目。减少(_计数,acc);
}
如果(所有项目中的项目){
所有项目[项目]+;
}否则{
所有项目[项目]=1;
}
返回acc;
}
//需要'source'作为数组
返回source.reduce(_count,{});
//如果“来源”是一种单一的动物,这也会起作用。
//像动物(“狗”);
//我更喜欢这种方法,因为它更灵活
//函数可以处理什么,
//它甚至不需要我额外的一行代码
//返回_计数({},源);
}
动物变量=[‘猫’、[‘猫’]、‘狗’、‘青蛙’];
console.log(“简单”,countAnimals(动物));
其他动物变量=[“猫”,“猫”,“猫”,“狗”,“青蛙];
console.log(“嵌套”,countAnimals(其他动物));
//和一个深嵌套的结构
var moreAnimals=[‘老鼠’、[‘猫’、[‘狗’、‘鸭’、[‘青蛙’]、‘猫’、‘狗’、‘青蛙’];
console.log(“多个级别”,countAnimals(moreAnimals))

.as控制台包装器{top:0;max height:100%!important}
如果您的数组只嵌套一层深度,您可以使用
[].concat(…arr)
在使用
reduce
对其进行迭代之前将其展平

在本例中,我还使条件更加简洁

var-animals=['cat','cat',['cat','dog','frog'];
其他动物变量=[“猫”,“猫”,“猫”,“狗”,“青蛙];
函数缩减阵列(arraySource){
return[].concat(…arraySource).reduce(函数(allItems,item){
allItems[项目]=allItems[项目]| | 0;
所有项目[项目]+;
返回allItems;
}, {});
}
常数结果=减少阵列(动物);
const result2=还原阵列(其他动物);
控制台日志(结果);

console.log(result2)
['cat']
被强制转换为
'cat'
<代码>['cat','cat']
被强制转换为
'cat,cat'
。您使用数组作为对象键,将它们转换为字符串。您需要某种递归函数。或者使用。