我在Angular2应用中使用Firebase从我的数据库中检索数据。在嵌套的标记列表中返回一组唯一值最简单的方法是什么?即在我的示例中,我想返回["Sport", "Adventure", "Music"]
,其中第二个"冒险" 被省略。
{
"images": {
"image1": {
"path": "path",
"date": 43534532123,
"tags": {
0: "Sport",
1: "Adventure"
}
},
"image2": {
"path": "path",
"date": 43534532123,
"tags": {
0: "Music",
1: "Adventure"
}
}
}
我尝试过这种方法,但它似乎只从第一张图片中拆分了元素
return this.af.database.list('/photos/user')
.map(photos => photos.map(photo => photo.tags))
.concatAll()
.distinct()
然而,这种方法产生正确的输出,但作为独特标记的单独流而不是作为一个数组
return this.af.database.list('/photos/user')
.map(photos => photos.map(photo => photo.tags))
.mergeAll()
.mergeAll()
.distinct()
答案 0 :(得分:2)
<强>更新强>
我在原始答案中假设它是一个包含各个项目的流。后来,OP澄清了它是 photos 列表的流。在这种情况下,我们使用Array#reduce
代替Observable#reduce
。
return this.af.database.list('/photos/user')
.map(photos => photos.map(photo => photo.tags)
.reduce((allTags, current) => {
return allTags.concat(
current.filter(item => allTags.indexOf(item) === -1))
}, []))
原始回答
distinct
对一个observable返回一个流中唯一的单个值,但不是我们想要的运算符。可以生成一个包含所有标签的序列,每个标签都作为一个单独的值,但是我们需要重新组合它们。
我们可以使用reduce
,非常类似于Array对应物。它采用初始值([]
)并累积其他值。我们在每次迭代中构建了一个包含各个值的列表。在reduce之后,我们有一系列独特的标签。
请注意.list()
应该完成observable才能工作。
return this.af.database.list('/photos/user')
.map(photos => photos.map(photo => photo.tags))
.reduce((allTags, current) => {
return allTags.concat(
current.filter(item => allTags.indexOf(item) === -1))
}, [])