简体   繁体   English

如何对数组多个对象的唯一属性的字段值求和?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM