计算Javascript中数组的Two对象的唯一值



给定一个类别数组和一个条目数组,创建一个具有类别名称和条目计数的对象数组。考虑id等于categoryId。

var categories = [
{ name: 'Cats', id: 10 },
{ name: 'Dogs', id: 20 },

];
var entries = [
{categoryId: 10, name: 'Fluffy'},
{categoryId: 10, name: 'Spot'},
{categoryId: 10, name: 'Lil'},
{categoryId: 20, name: 'Tom'},
{categoryId: 20, name: 'Buck'},
{categoryId: 20, name: 'Flo'},
{categoryId: 20, name: 'Cheek'},
{categoryId: 10, name: 'Stan'},
{categoryId: 20, name: 'Stila'}

]
Expected Output: [{ name:'Cats', count: 4 }, { name:'Dogs', count: 5 }];

我在下面这样写,但当你试图在数百个类别和数万个条目中运行它时,似乎会出现性能问题。

const categoriesByEntryCount = (categories, entries) =>
categories.map(category => ({
name: category.name,
count: entries.filter(entry => entry.categoryId === category.id).length,
}));

我的问题是,还有其他方法可以写或实现这个吗?

您需要在所有可能的地方使用Maps

var categories = new Map();
categories.set(10, 'Cats');
categories.set(20, 'Dogs');
var entries = [
{ categoryId: 10, name: 'Fluffy' },
{ categoryId: 10, name: 'Spot' },
{ categoryId: 10, name: 'Lil' },
{ categoryId: 20, name: 'Tom' },
{ categoryId: 20, name: 'Buck' },
{ categoryId: 20, name: 'Flo' },
{ categoryId: 20, name: 'Cheek' },
{ categoryId: 10, name: 'Stan' },
{ categoryId: 20, name: 'Stila' },
];
console.log(Array.from(
entries.reduce(
(m, { categoryId, name }) =>
m.set(categoryId, (m.get(categoryId) || 1) + 1),
new Map()
),
([k, v]) => ({ name: categories.get(k), count: v })
));

const categories = [ { name: 'Cats', id: 10 }, { name: 'Dogs', id: 20 } ];
const entries = [ { categoryId: 10, name: 'Fluffy' }, { categoryId: 10, name: 'Spot' }, { categoryId: 10, name: 'Lil' }, { categoryId: 20, name: 'Tom' }, { categoryId: 20, name: 'Buck' }, { categoryId: 20, name: 'Flo' }, { categoryId: 20, name: 'Cheek' }, { categoryId: 10, name: 'Stan' }, { categoryId: 20, name: 'Stila' } ];
// get number of occurences of each category in entries
const categoriesCount = entries.reduce((countMap, { categoryId }) => 
countMap.set( categoryId, 1 + (countMap.get(categoryId) || 0) )
, new Map);
// iterate over categories and return name and count in categoriesCount
const res = categories.map(({ name, id }) => 
({ name, count: categoriesCount.get(id) })
);
console.log(res);

我们可以像下面这样处理时间复杂性O(M+N(

var categories = [
{ name: 'Cats', id: 10 },
{ name: 'Dogs', id: 20 },

];
var entries = [
{categoryId: 10, name: 'Fluffy'},
{categoryId: 10, name: 'Spot'},
{categoryId: 10, name: 'Lil'},
{categoryId: 20, name: 'Tom'},
{categoryId: 20, name: 'Buck'},
{categoryId: 20, name: 'Flo'},
{categoryId: 20, name: 'Cheek'},
{categoryId: 10, name: 'Stan'},
{categoryId: 20, name: 'Stila'}

]
const categoriesByEntryCount = (categories, entries) => {
const entriesHash = entries.reduce((acc, ele) => {
acc[ele.categoryId] =  acc[ele.categoryId] ? acc[ele.categoryId] + 1 : 1;
return acc;
}, {});

return categories.map(category => ({
name: category.name,
count: entriesHash[category.id],
}));
}

console.log(categoriesByEntryCount(categories, entries))

这显然是一项减少工作量的工作。

var categories = [ { name: 'Cats', id: 10 }
, { name: 'Dogs', id: 20 }
],
entries    = [ {categoryId: 10, name: 'Fluffy'}
, {categoryId: 10, name: 'Spot'}
, {categoryId: 10, name: 'Lil'}
, {categoryId: 20, name: 'Tom'}
, {categoryId: 20, name: 'Buck'}
, {categoryId: 20, name: 'Flo'}
, {categoryId: 20, name: 'Cheek'}
, {categoryId: 10, name: 'Stan'}
, {categoryId: 20, name: 'Stila'}
],
result     = entries.reduce((cs,e) => ( cs.map(c => c.id === e.categoryId ? c.count ? c.count++
                  : c.count = 1
        : c)
, cs
), categories);
console.log(result);

您可能会抱怨结果包含id属性,但这很好。

最新更新