任何人都可以向我解释这种情况吗?
在第二次调用函数时,结果为{cat: 2, cat,cat: 1, dog: 1, frog: 1}
。
但是,我认为结果将是{cat: 4, dog: 1, frog: 1}
。
这里发生了什么?
var animals = ['cat', 'cat', ['cat'], 'dog', 'frog'];
var otherAnimals = ['cat', 'cat', ['cat', 'cat'], 'dog', 'frog'];
function reducingArrays(arraySource) {
var countedData = arraySource.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: 2, cat,cat: 1, dog: 1, frog: 1}
// What I expected: {cat: 4, dog: 1, frog: 1}
答案 0 :(得分:1)
您可以将单个元素转换为数组:
var animals = ['cat', 'cat', ['cat'], 'dog', 'frog'];
var otherAnimals = ['cat', 'cat', ['cat', 'cat'], 'dog', 'frog'];
function reducingArrays(arraySource) {
var countedData = arraySource.reduce(function(allItems, item) {
var arr = Array.isArray(item) ? item : [item];
allItems[arr[0]] = (allItems[arr[0]] || 0) + arr.length;
return allItems;
}, {});
console.log(countedData);
}
reducingArrays(animals);
reducingArrays(otherAnimals);

答案 1 :(得分:0)
如果其中一个对象是数组,则必须处理:
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);
}
答案 2 :(得分:0)
Yoh可以使用对数组的检查,并对嵌套数组使用reduce
的相同回调。
function reducingArrays(arraySource) {
return arraySource.reduce(function iter(allItems, item) {
if (Array.isArray(item)) {
return item.reduce(iter, allItems);
}
allItems[item] = (allItems[item] || 0) +1;
return allItems;
}, {});
}
var animals = ['cat', 'cat', ['cat'], 'dog', 'frog'];
var otherAnimals = ['cat', 'cat', ['cat', 'cat'], 'dog', 'frog'];
console.log(reducingArrays(animals)); // { cat: 3, dog: 1, frog: 1}
console.log(reducingArrays(otherAnimals)); // { cat: 4, dog: 1, frog: 1 }

答案 3 :(得分:0)
第一条评论已经解释过,这与数组的字符串化有关,因为对象键只能是字符串。
这是一种如何在函数中处理嵌套数组的方法。
function countAnimals(source) {
function _count(allItems, item) {
if (Array.isArray(item)) {
return item.reduce(_count, acc);
}
if (item in allItems) {
allItems[item]++;
} else {
allItems[item] = 1;
}
return acc;
}
//needs `source` to be an Array
return source.reduce(_count, {});
//this would also work, if `source` is a single animal.
//like countAnimals('dog');
//I prefer this approach because it is more flexible
//on what the function can deal with,
//and it doesn't cost me even a single extra line of code
//return _count({}, source);
}
var animals = ['cat', 'cat', ['cat'], 'dog', 'frog'];
console.log("simple", countAnimals(animals));
var otherAnimals = ['cat', 'cat', ['cat', 'cat'], 'dog', 'frog'];
console.log("nested", countAnimals(otherAnimals));
//and a deeply nested structure
var moreAnimals = ['mouse', ['cat', ['dog', 'duck', ['frog']], 'cat'], 'dog', 'frog'];
console.log("multiple levels", countAnimals(moreAnimals));
.as-console-wrapper{top: 0;max-height: 100%!important}
答案 4 :(得分:0)
如果您的数组只是嵌套一层,您可以使用[].concat(...arr)
展平它,然后再使用reduce
进行迭代。
在这个例子中,我也使条件更简洁。
var animals = ['cat', 'cat', ['cat'], 'dog', 'frog'];
var otherAnimals = ['cat', 'cat', ['cat', 'cat'], 'dog', 'frog'];
function reducingArrays(arraySource) {
return [].concat(...arraySource).reduce(function(allItems, item) {
allItems[item] = allItems[item] || 0;
allItems[item]++;
return allItems;
}, {});
}
const result = reducingArrays(animals);
const result2 = reducingArrays(otherAnimals);
console.log(result);
console.log(result2);