在Javascript中从两个对象数组中计算唯一值的数量

3
给定一个类别数组和一个条目数组,创建一个由类别名称和条目计数组成的对象数组。假设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,
  }));

我的问题是是否有其他方式来编写或实现这个?

4个回答

1

您需要在所有可能的地方使用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 })
));


0

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);


0
我们可以使用时间复杂度为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))


0

这显然是一个简化工作。

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属性,但那是很好的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接