有没有更好的方法使用 Lodash 库重构这个函数?

Is there a better way to refactor this function using the Lodash library?

我的目标是获取博客列表并找到拥有最多博客的作者返回这样的对象 { author: String, blogs: Number }。我成功了,但我想知道使用 Lodash 解决我的问题的更好方法。谢谢!

let blogs = [
    { title: 'sorceror stone', author: 'rowling', likes: 5 },
    { title: 'prisoner of azkaban', author: 'rowling', likes: 13 },
    { title: 'green mile', author: 'king', likes: 3 },
    { title: 'oliver twist', author: 'dickens', likes: 7 },
    { title: 'the half blood prince', author: 'rowling', likes: 16 },
    { title: 'david copperfield', author: 'dickens', likes: 10 },
    { title: 'christmas carol', author: 'dickens', likes: 3 },
    { title: 'tale of two cities', author: 'dickens', likes: 20 },
]

const mostBlogs = (blogs) => {
    let authorsByBlogs = _.countBy(blogs, 'author')

    let maxBlogs = _.max(_.values(authorsByBlogs))

    let author = _.findKey(authorsByBlogs, (o) => {
        return o === maxBlogs
    })

    return { author: author, blogs: maxBlogs }
}

console.log(mostBlogs(blogs)) // { author: "dickens", blogs: 4}

这是使用 lodash 的 _.flow() 对您的函数进行的重构(请参阅代码中的注释):

const { flow, countBy, toPairs, maxBy, last, zipObject } = _

const mostBlogs = flow(
  blogs => countBy(blogs, 'author'), // count by the author
  toPairs, // convert to array of [key, value] pairs
  blogs => maxBy(blogs, last), // get the entry with most blogs
  blog => zipObject(['author', 'blogs'], blog) // convert to an object
)

const blogs = [{"title":"sorceror stone","author":"rowling","likes":5},{"title":"prisoner of azkaban","author":"rowling","likes":13},{"title":"green mile","author":"king","likes":3},{"title":"oliver twist","author":"dickens","likes":7},{"title":"the half blood prince","author":"rowling","likes":16},{"title":"david copperfield","author":"dickens","likes":10},{"title":"christmas carol","author":"dickens","likes":3},{"title":"tale of two cities","author":"dickens","likes":20}]

const result = mostBlogs(blogs)

console.log(result) // { author: "dickens", blogs: 4}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG+ljU96qKRCWh+quCY7yefSmlkQw1ANQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

同样的想法使用 lodash/fp:

const { flow, countBy, toPairs, maxBy, last, zipObject } = _

const mostBlogs = flow(
  countBy('author'), // count by the author
  toPairs, // convert to array of [key, value] pairs
  maxBy(last), // get the entry with most blogs
  zipObject(['author', 'blogs']) // convert to an object
)

const blogs = [{"title":"sorceror stone","author":"rowling","likes":5},{"title":"prisoner of azkaban","author":"rowling","likes":13},{"title":"green mile","author":"king","likes":3},{"title":"oliver twist","author":"dickens","likes":7},{"title":"the half blood prince","author":"rowling","likes":16},{"title":"david copperfield","author":"dickens","likes":10},{"title":"christmas carol","author":"dickens","likes":3},{"title":"tale of two cities","author":"dickens","likes":20}]

const result = mostBlogs(blogs)

console.log(result) // { author: "dickens", blogs: 4}
<script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>