[英]How to sum values of fields for a unique property of an array multiple objects?
So I have this data, which contains an array of objects, the objects are blogs info, and they have authors, title, likes, link, etc.所以我有这个数据,其中包含一组对象,这些对象是博客信息,它们有作者、标题、喜欢、链接等。
What I wan't to do is get the author with the most likes across this array of data.我不想做的是让作者在这组数据中获得最多的赞。
const blogs = [ { _id: "5a422a851b54a676234d17f7", title: "React patterns", author: "Michael Chan", url: "https://reactpatterns.com/", __v: 0 }, { _id: "5a422aa71b54a676234d17f8", title: "Go To Statement Considered Harmful", author: "Edsger W. Dijkstra", url: "http://www.u.arizona.edu/~rubinson/copyright_violations/Go_To_Considered_Harmful.html", likes: null, __v: 0 }, { _id: "5a422b3a1b54a676234d17f9", title: "Canonical string reduction", author: "Edsger W. Dijkstra", url: "http://www.cs.utexas.edu/~EWD/transcriptions/EWD08xx/EWD808.html", likes: 12, __v: 0 }, { _id: "5a422b891b54a676234d17fa", title: "First class tests", author: "Robert C. Martin", url: "http://blog.cleancoder.com/uncle-bob/2017/05/05/TestDefinitions.htmll", likes: 10, __v: 0 }, { _id: "5a422ba71b54a676234d17fb", title: "TDD harms architecture", author: "Robert C. Martin", url: "http://blog.cleancoder.com/uncle-bob/2017/03/03/TDD-Harms-Architecture.html", likes: 0, __v: 0 }, { _id: "5a422bc61b54a676234d17fc", title: "Type wars", author: "Robert C. Martin", url: "http://blog.cleancoder.com/uncle-bob/2016/05/01/TypeWars.html", likes: 2, __v: 0 }
for example:例如:
getAuthorWithMostLikes(blogs)
And it would check the array, sum the number of likes for every author across every article and return for example:它会检查数组,将每篇文章中每个作者的点赞数相加,并返回例如:
{author: Robert C. Martin, totalLikes: 12}
How can I achieve this in a clean way?我怎样才能以干净的方式实现这一目标? I already "solved" it but I think the code is pretty messy and not readable我已经“解决”了它,但我认为代码非常混乱且不可读
Here's my code:这是我的代码:
const likesByAuthor = (blogs) =>{
const blogsWhereThereIsAnAuthor = blogs.filter(blog=> blog.author)
console.log("length of filtered array", blogsWhereThereIsAnAuthor.length)
let authorsAndLikes = []
let contin = undefined;
blogsWhereThereIsAnAuthor.forEach((blog, index) => {
let author = blog.author;
let likes = blog.likes;
// initialize concentrado
console.log("loop for: ", author)
if (!likes){
return false
}
if (authorsAndLikes.length < 1){
authorsAndLikes.push({author, likes})
console.log("initial data", authorsAndLikes)
return
}
authorsAndLikes.forEach((item) => {
console.log(item.author, "|", blog.author, item.author === blog.author)
if (item.author === blog.author) {
console.log("case 1: existing author", item.author, "|", blog.author)
console.log(item)
item.likes += blog.likes;
console.log(item)
console.log(authorsAndLikes)
contin = false;
return false;
}
contin = true;
})
if (contin !== false) {
console.log("case 2: new author, adding it to concentrado array", blog.author)
authorsAndLikes.push({"author": author, "likes": likes})
console.log(authorsAndLikes)
console.log("end of iteration case 2")
}
})
return authorsAndLikes;
}
const mostLikes = (blogs) =>{
const likesCountByAuthor = likesByAuthor(blogs)
return likesCountByAuthor.reduce((curr, sum) => curr.likes > sum.likes ? curr : sum)
}
How can I achieve the same result with more clean code or in a more efficient way?如何使用更简洁的代码或更有效的方式获得相同的结果?
One way to do this a little more cleanly is to create a single object like this:一种更简洁的方法是创建一个 object,如下所示:
{
author: likes
}
instead of a list of objects.而不是对象列表。 If you want the list instead, this object can be morphed into a list pretty easily.如果你想要这个列表,这个 object 可以很容易地变成一个列表。
My solution takes advantage of reduce()
:我的解决方案利用了reduce()
:
const likesByAuthor = (blogs) =>{
return blogs.reduce((likes, blog) => {
if (blog.likes)
if (likes[blog.author])
likes[blog.author] += blog.likes;
else
likes[blog.author] = blog.likes;
return likes;
}, {});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.