我在我的 Angular2 应用程序中使用 Firebase 从我的数据库中检索数据。最简单的方法是在嵌套的 tags 列表中返回一组唯一值? IE。在我的示例中,我想返回 ["Sport", "Adventure", "Music"]
,其中省略了第二个 "Adventure"。
{
"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()
最佳答案
更新
我在最初的回答中假设它是一个包含各个项目的流。后来 OP 澄清说它是 照片 列表的流。在这种情况下,我们使用 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
over observable 返回流中唯一的单个值,但这不是我们在这里想要的运算符。可以生成一个包含所有标签的序列,每个标签作为一个单独的值,但是我们需要再次将它们重新组合。
我们可以改用 reduce
,这与对应的数组非常相似。它采用初始值 ([]
) 并累加其他值。我们在每次迭代中构建了一个包含各个值的列表。在 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))
}, [])
关于javascript - 展平 Angular2 中的可观察数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40918280/