在不完整的 RxJS 流中展平嵌套数据结构
Flatten nested data-structure in a non-complete RxJS stream
我想展平从商店获得的值,并在商店发出时将它们作为单个数组发出。
在下面我的 No-RxJS 示例中的同步版本中非常容易,但我无法弄清楚如何使用 RxJS 做到这一点。
我假设我可以使用 RxJS 来缓冲来自单个 .next
调用的值。
我应该为此使用 RxJS 运算符吗?如果是,那么如何将嵌套数据结构扁平化?
这是我要实现的目标的最小示例。
const store$ = new Rx.BehaviorSubject([])
store$.next([
{
id: 1,
items: [
{
id: 1,
title: 'Foo'
},
{
id: 2,
title: 'Bar'
}
]
},
{
id: 2,
items: [
{
id: 3,
title: 'Fizz'
},
{
id: 4,
title: 'Buzz'
}
]
},
]);
// Desired output: [ "Foo", "Bar", "Fizz", "Buzz" ]
store$
.filter(({length}) => length > 0)
.flatMap(group => group)
.flatMap(({items}) => items)
.map(({title}) => title)
.subscribe(console.log) // Emits separate values :-(
// No-RxJs approach
store$
.filter(({length}) => length > 0)
.map(groups => groups
.map(
({ items }) => items.map(
({ title }) => title
)
)
.reduce((next, acc) => [ ...acc, ...next ], []))
.subscribe(console.log) // Works as expected.
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.0.1/Rx.js"></script>
正如 @zeroflagl in comments, toArray 所建议的那样,方法非常有效。
因为它只适用于已完成的可观察对象,所以我不得不 swithchMap
到一个可观察对象,它使用 take(1)
来获得具有当前存储值的已完成可观察对象。
store$
.filter(({ length }) => length > 0)
.switchMap(() => store$.take(1)
.flatMap(group => group)
.flatMap(({ items }) => items)
.map(({ title }) => title)
.toArray()
)
.subscribe(console.log) // Emits flat array
我想展平从商店获得的值,并在商店发出时将它们作为单个数组发出。
在下面我的 No-RxJS 示例中的同步版本中非常容易,但我无法弄清楚如何使用 RxJS 做到这一点。
我假设我可以使用 RxJS 来缓冲来自单个 .next
调用的值。
我应该为此使用 RxJS 运算符吗?如果是,那么如何将嵌套数据结构扁平化?
这是我要实现的目标的最小示例。
const store$ = new Rx.BehaviorSubject([])
store$.next([
{
id: 1,
items: [
{
id: 1,
title: 'Foo'
},
{
id: 2,
title: 'Bar'
}
]
},
{
id: 2,
items: [
{
id: 3,
title: 'Fizz'
},
{
id: 4,
title: 'Buzz'
}
]
},
]);
// Desired output: [ "Foo", "Bar", "Fizz", "Buzz" ]
store$
.filter(({length}) => length > 0)
.flatMap(group => group)
.flatMap(({items}) => items)
.map(({title}) => title)
.subscribe(console.log) // Emits separate values :-(
// No-RxJs approach
store$
.filter(({length}) => length > 0)
.map(groups => groups
.map(
({ items }) => items.map(
({ title }) => title
)
)
.reduce((next, acc) => [ ...acc, ...next ], []))
.subscribe(console.log) // Works as expected.
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.0.1/Rx.js"></script>
正如 @zeroflagl in comments, toArray 所建议的那样,方法非常有效。
因为它只适用于已完成的可观察对象,所以我不得不 swithchMap
到一个可观察对象,它使用 take(1)
来获得具有当前存储值的已完成可观察对象。
store$
.filter(({ length }) => length > 0)
.switchMap(() => store$.take(1)
.flatMap(group => group)
.flatMap(({ items }) => items)
.map(({ title }) => title)
.toArray()
)
.subscribe(console.log) // Emits flat array