【问题标题】:How to groupby in lodash for each item in a nested array如何在lodash中为嵌套数组中的每个项目分组
【发布时间】:2019-04-01 07:33:55
【问题描述】:

我有一个 json 数组,格式如下:

    [{
        "published": true,
        "tags": ["tag1", "tag2"],
        "categories": ["cat1"],
        "author": "some name",
        "post-format": "standard",
        "title": "Second Post,",
        "url-slug": "second-post",
        "first-published-on": "2019-03-28",
        "last-updated-on": "2019-03-28",
        "meta": {
            "title": "Second Post",
            "description": "Second post."
        },
        "excerpt": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt",
        "path": "2019/03/28/SecondPost.md"
    }, {
        "published": true,
        "tags": ["tag1", "tag2", "tag3"],
        "categories": ["cat1", "cat2"],
        "author": "some name",
        "post-format": "standard",
        "title": "Getting Started",
        "url-slug": "getting-started",
        "first-published-on": "2019-03-20",
        "last-updated-on": "2019-03-20",
        "meta": {
            "title": "Getting Started",
            "description": "Getting started post."
        },
        "excerpt": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt",
        "path": "2019/03/20/GettingStarted.md"
    }]

我想按标签对它们进行分组,格式如下:

[{
   "tag1": [{...}, {...}], 
   "tag2": [{...}, {...}], 
   "tag3": [{...}]
}]

我曾尝试使用 lodash:

const groupedByTag = _.groupBy(blogMetadata, function(postmetadata) {
        postmetadata.tags.map(tag => {
          return tag
        })
      })

显然上面的代码不正确并且不起作用。我查看了相关的post,但没有取得太大进展。任何帮助表示赞赏。

【问题讨论】:

  • 你可以试试 reduce 或 'json-groupby' nodejs 模块。

标签: javascript arrays json grouping lodash


【解决方案1】:

您可以使用reduceforEach 来替代loadash。在reduce回调函数内部迭代tags并检查累加器对象是否存在同名的key。如果存在则推送当前对象,否则创建key 并推送value

let data = [{
  "published": true,
  "tags": ["tag1", "tag2"],
  "categories": ["cat1"],
  "author": "some name",
  "post-format": "standard",
  "title": "Second Post,",
  "url-slug": "second-post",
  "first-published-on": "2019-03-28",
  "last-updated-on": "2019-03-28",
  "meta": {
    "title": "Second Post",
    "description": "Second post."
  },
  "excerpt": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt",
  "path": "2019/03/28/SecondPost.md"
}, {
  "published": true,
  "tags": ["tag1", "tag2", "tag3"],
  "categories": ["cat1", "cat2"],
  "author": "some name",
  "post-format": "standard",
  "title": "Getting Started",
  "url-slug": "getting-started",
  "first-published-on": "2019-03-20",
  "last-updated-on": "2019-03-20",
  "meta": {
    "title": "Getting Started",
    "description": "Getting started post."
  },
  "excerpt": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt",
  "path": "2019/03/20/GettingStarted.md"
}];

let newMapped = [data.reduce(function(acc, curr) {
  curr.tags.forEach(function(item) {
    if (acc[item]) {
      acc[item].push(curr)
    } else {
      acc[item] = [curr]
    }

  })
  return acc;
}, {})];


console.log(newMapped)

【讨论】:

    【解决方案2】:

    您可以使用reduceforEach

    这里的想法是

    • 首先我们循环遍历obj 变量的每个元素。
    • 对于每个元素,我们都会遍历tags 属性。
    • 我们检查 op 是否已经有那个标签,我们推送值,否则我们添加一个新键到 op 具有相应值的对象

    let obj = [{"published": true,"tags": ["tag1", "tag2"],"categories": ["cat1"],"author": "some name","post-format": "standard","title": "Second Post,","url-slug": "second-post","first-published-on": "2019-03-28","last-updated-on": "2019-03-28","meta": {"title": "Second Post","description": "Second post."},"excerpt": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt","path": "2019/03/28/SecondPost.md"}, {"published": true,"tags": ["tag1", "tag2", "tag3"],"categories": ["cat1", "cat2"],"author": "some name","post-format": "standard","title": "Getting Started","url-slug": "getting-started","first-published-on": "2019-03-20","last-updated-on": "2019-03-20","meta": {"title": "Getting Started","description": "Getting started post."},"excerpt": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt","path": "2019/03/20/GettingStarted.md"}]
    
    let final = obj.reduce((op,inp) => {
      inp.tags.forEach(e => {
        op[e] = op[e] || []
        op[e].push(JSON.parse(JSON.stringify(inp)))
      }) 
      return op
    },{})
    
    console.log(final)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-16
      • 1970-01-01
      • 1970-01-01
      • 2018-11-16
      • 1970-01-01
      • 2017-06-15
      • 1970-01-01
      相关资源
      最近更新 更多