如何在一个对象数组中找到五个最常见的元素,并使用.reduce()将它们相加



对于学校,我需要在书籍对象列表中找到最常见的流派。我必须使用reduce((创建一个新对象,并计算该类型的书籍总数。预期输出看起来像这个

[
{ name: "Nonfiction", count: 9 },
{ name: "Historical Fiction", count: 7 },
{ name: "Thriller", count: 7 },
...
]

图书列表包含许多类似的图书对象。

books = [
{
id: "5f447132320b4bc16f950076",
title: "est voluptate nisi",
genre: "Classics",
authorId: 12,
author: {
id: 12,
name: {
first: "Chrystal",
last: "Lester",
}
}
},
{
id: "5f447132320b4bc16f950176",
title: "The Name of the Wind",
genre: "Fantasy",
authorId: 10,
author: {
id: 10,
name: {
first: "Patrick",
last: "Rothfuss",
}
}
}
]

我必须再次使用reduce函数来执行此操作。这就是我现在拥有的

function mostCommonGenres(books) {
let values = Object.values(books)
let total = 0

const genres = values.reduce((acc, val) => {
let {id,title,genre,authorId,borrows} = val
return {...acc, ['name']: genre, ...acc, ['count']: total++}
}, {})
return genres
}

问题是,它并不是只遍历第一个对象就遍历每个对象。此外,总变量总是数组的长度-1。

首先让我们创建两个辅助函数:

第一种是使用给定的密钥对数组中的项目进行分组,即:

/**
* Helper function to group items in an array using the given key
* 
* @param {*} array 
* @param {*} key 
*/
function groupByKey(array, key) {
return array
.reduce((hash, obj) => {
if(obj[key] === undefined) return hash; 
return Object.assign(hash, { [obj[key]]:( hash[obj[key]] || [] ).concat(obj)})
}, {});
}

第二个是获取对象的大小,即:

/**
* Helper function to get the size of an object
* 
* @param {*} obj 
*/
Object.size = function(obj) {
var size = 0, key;
for (key in obj) {
if (obj.hasOwnProperty(key)) size++;
}
return size;
};

给定我们的图书列表,即:

/**
* List of books
*/
books = [
{
id: "5f447132320b4bc16f950076",
title: "est voluptate nisi",
genre: "Classics",
authorId: 12,
author: {
id: 12,
name: {
first: "Chrystal",
last: "Lester",
}
}
},
{
id: "5f447132320b4bc16f950176",
title: "The Name of the Wind",
genre: "Fantasy",
authorId: 10,
author: {
id: 10,
name: {
first: "Patrick",
last: "Rothfuss",
}
}
}
];

这就是我们将如何使用我们的助手功能:

/**
* Group all books using genre
*/
const genres = groupByKey(books, 'genre');
// Initialize empty array to hold results
let results = [];
/**
* Create new object with genre & count
*/
for (const key in genres) {
results.push({
name: key,
count: Object.size(genres[key]),
})
}
/**
* Echo results to view the results
*/
console.log(results);

以下是一个文件中的完整代码:

/**
* Helper function to group items in an array using the given key
* 
* @param {*} array 
* @param {*} key 
*/
function groupByKey(array, key) {
return array
.reduce((hash, obj) => {
if(obj[key] === undefined) return hash; 
return Object.assign(hash, { [obj[key]]:( hash[obj[key]] || [] ).concat(obj)})
}, {});
}
/**
* Helper function to get the size of an object
* 
* @param {*} obj 
*/
Object.size = function(obj) {
var size = 0, key;
for (key in obj) {
if (obj.hasOwnProperty(key)) size++;
}
return size;
};

/**
* List of books
*/
books = [
{
id: "5f447132320b4bc16f950076",
title: "est voluptate nisi",
genre: "Classics",
authorId: 12,
author: {
id: 12,
name: {
first: "Chrystal",
last: "Lester",
}
}
},
{
id: "5f447132320b4bc16f950176",
title: "The Name of the Wind",
genre: "Fantasy",
authorId: 10,
author: {
id: 10,
name: {
first: "Patrick",
last: "Rothfuss",
}
}
}
];
/**
* Group all books using genre
*/
const genres = groupByKey(books, 'genre');
// Initialize empty array to hold result
let results = [];
/**
* Create new object with genre & count
*/
for (const key in genres) {
results.push({
name: key,
count: Object.size(genres[key]),
})
}
/**
* Echo results
*/
console.log(results);

最新更新