我有一个带有发布主题的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输出,仅按标签排序。
谢谢您的建议!
答案 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脚本编辑器的默认设置,记下了对象之间的共享引用。
在这里,我们可以看到tags1
和tags3
都包含对ID为9551的单个输出对象的引用。这对您的代码而言可能不重要,但很高兴知道在这里完成。