我收到一个HTTP响应,如果一切顺利,它包含一个编码为JSON的单个数组。
我想获取此数组,过滤掉一些项目,并将通过的项目作为事件进行处理。
到目前为止,我要做的是:
return this._http.get(url)
.map((res:Response) => res.json())
.map((data:any) => {
if (!Array.isArray(data) || data.length == 0) {
throw new Error("No items returned, URL: " + url);
}
let projects = <ProjectModel[]>service.fromJSONarray(data, this._http);
return Observable.from(projects)
.filter((project: ProjectModel) => project.parentProject == null)
.subscribe(project -> ...)
})
但是我不喜欢嵌套。我认为有一种方法可以做到这一点:
return this._http.get(url)
.map((res:Response) => res.json())
.map((data:any) => {
...
let projects = <ProjectModel[]>service.fromJSONarray(data, this._http);
???
})
.filter((project: ProjectModel) => project.parentProject == null)
.subscribe(project -> ...)
如何实现呢?
最佳答案
假设您使用的是RxJS 5,即使concatAll()
与高阶Observable一起使用,也可以使用concatAll()
及其未公开的功能来简化嵌套数组的更简单方法。
let data = '[{"id":1},{"id":2},{"id":3},{"id":4}]';
Observable.of(data)
.map(JSON.parse)
.concatAll() // each object is emitted separately
.map(p => p) // transform to ProjectModel
.filter(p => true) // filter whatever you want
.subscribe(v => console.log(v));
如果
service.fromJSONarray
仅返回ProjectModel
的单个实例,则可以很简单。如果您需要service.fromJSONarray
返回一个数组,可以将其放在map(JSON.parse)
和concatAll()
之间。该演示打印到控制台:{ id: 1 }
{ id: 2 }
{ id: 3 }
{ id: 4 }
但是,如果您要从
service.fromJSONarray
返回一个Observable,因为它需要执行一些额外的HTTP请求,则它会发出其他Observable,因此您需要使用concatMap()
或flatMap()
取决于您是否要保持相同的顺序:let data = '[{"id":1},{"id":2},{"id":3},{"id":4}]';
function fromJSONarray(arr) {
return Observable.from(arr)
.flatMap(p => Observable.of(p));
}
Observable.of(data)
.map(d => fromJSONarray(JSON.parse(d)))
.concatAll()
.map(p => p) // transform to ProjectModel
.subscribe(v => console.log(v));
结果是一样的。
类似问题:
关于javascript - RxJS:带有数组的JSON数据,进一步处理流中的每个项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41092488/