通过标签重组嵌套的JSON数据-Javascript

时间:2019-06-07 14:07:22

标签: javascript arrays json

我有一个带有发布主题的JSON文件:

"topics": [
  {
    "id": "9551",
    "tags": ["tag1", "tag2"],
    "title": "title"
   },
   {
    "id": "9552",
    "tags": ["tag3"],
    "title": "title2"
   },
   {
    "id": "9553",
    "tags": ["tag1"],
    "title": "title3"
   }
]

我想按标签对这些帖子进行排序,如下所示:

 "tags" : {
     "tag1": [
         { "id": "9951",
           "title": "title"
          },
          {
          "id": "9553",
          "title": "title3"
          }
     ],
     "tag2": [
        {
        "id": "9551",
        "title": "title"
       }
      ]
    }

我不确定以上内容是否有效,但从本质上来说,我想要原始数据的有效JSON输出,仅按标签排序。

谢谢您的建议!

2 个答案:

答案 0 :(得分:2)

您可以使用reduce对标签进行分组。创建一个累加器,每个标签都为key。在reduce内部,遍历每个tags。如果已经添加了tag,则将{ id, title }对象推到数组中。否则,为该标签创建一个新数组,然后将其推送。

const topics=[{"id":"9551","tags":["tag1","tag2"],"title":"title"},{"id":"9552","tags":["tag3"],"title":"title2"},{"id":"9553","tags":["tag1"],"title":"title3"}]

const group = topics.reduce((acc, { id, tags, title }) => {
  tags.forEach(t => {
    acc[t] = acc[t] || [];
    acc[t].push({ id, title })
  })
  return acc;
}, {})

console.log({ tags: group })

答案 1 :(得分:0)

另一种版本不会将输出结构固定为{id, title},而是保留其中的内容,并从每个对象中仅删除tags,如下所示:

const byTag = (topics) => topics.reduce(
  (a, {tags = [], ...rest}) => tags.reduce(
    (a, tag) => ({...a, [tag] : [...(a[tag] || []), rest]}), 
    a
  ), {}
)

const topics= [{id: "9551", tags: ["tag1", "tag2"], title: "title"}, {id: "9552", tags: ["tag3"], title: "title2"}, {id: "9553", tags: ["tag1"], title: "title3"}];

log ( byTag (topics) )
console .log ( byTag (topics) )
<script>  const log = (obj) => console.log(JSON.parse(JSON.stringify(obj)))  </script>

但是,如果要执行此操作,则使此泛型化仅相隔仅一步,因此它可以在任何包含字符串数组的公共属性上工作:

const groupByProp = (name) => (xs) => xs.reduce(
  (a, {[name]: n = [], ...rest}) => n.reduce(
    (a, x) => ({...a, [x] : [...(a[x] || []), rest]}), 
    a
  ), {}
)

const byTag = groupByProp ('tags')

const topics= [{id: "9551", tags: ["tag1", "tag2"], title: "title"}, {id: "9552", tags: ["tag3"], title: "title2"}, {id: "9553", tags: ["tag1"], title: "title3"}];

log ( byTag (topics) )
console .log ( byTag (topics) )
<script>  const log = (obj) => console.log(JSON.parse(JSON.stringify(obj)))  </script>

该技术的另一个优点是,当新数据结构中的项目具有多个标签时,它们不会重复。相反,每个对象都是对同一对象的引用。通过比较每个样本中的两个不同的日志输出,可以看到我在说什么。其中之一显示数据结构,因为JSON.stringify可能会显示它。第二个是StackOverflow脚本编辑器的默认设置,记下了对象之间的共享引用。

在这里,我们可以看到tags1tags3都包含对ID为9551的单个输出对象的引用。这对您的代码而言可能不重要,但很高兴知道在这里完成。