如何将 RxJS 三重'of(...).pipe.map(...)'表达式转换为三维数组的可观察量



我有这样的表达式:

var s2 = of(6, 16, 26).pipe(
map(v1=>of(5, 15, 25).pipe(
map(v2=>[v1,v2])
)), 
combineLatestAll());
s2.subscribe(console.log)

s2是我想要的CCD_ 1类型的

我可以用类似于Observable<number[][][]>的方式转换以下表达式吗(而不是Observable<Observable<number[]>[]>(:

var r2 = of(5, 15, 25).pipe(
map(v1=>of(6, 16, 26).pipe(
map(v2=>of(7, 17, 27).pipe(
map(v3 => [v1,v2,v3])
)))),
combineLatestAll());
//Print the output:
r2.subscribe(e1 => {
e1.forEach(e2 => {
e2.subscribe(e3 => {
console.log(e3);
});
})
});

我无法理解。任何帮助都很感激。

Ruth建议的解决方案:

let s3: Observable<number> = of(5, 15, 25);
let s4: Observable<number> = of(6, 16, 26);
let s5: Observable<number> = of(7, 17, 27);
const r1 = s3.pipe(
map((v3: number) =>
s4.pipe(
mergeMap((v4: number) =>
s5.pipe(
reduce((acc: number[][], v5: number, i5: number) => {
acc[i5] = [v3, v4, v5];
return acc;
}, [])
)
)
)
),
combineLatestAll()//reduce((acc: number[][], curr: number[][]) => [...acc, curr], [])
)
r1.subscribe(console.log);

看起来你可以只使用toArray()运算符,但很难理解嵌套的调用,所以我不确定这是否是你想要的:(:

var r2 = of(5, 15, 25).pipe(
map(v1=>of(6, 16, 26).pipe(
map(v2=>of(7, 17, 27).pipe(
map(v3 => [v1,v2,v3]),
toArray(),
)))),
combineLatestAll());

现场演示:https://stackblitz.com/edit/rxjs-veofem?devtoolsheight=60

或者,如果你想避免嵌套的Observable,你需要mergeMap:


var r2 = of(5, 15, 25).pipe(
map(v1=>of(6, 16, 26).pipe(
mergeMap(v2=>of(7, 17, 27).pipe(
map(v3 => [v1,v2,v3]),
toArray(),
)))),
combineLatestAll());
r2.subscribe(e1 => {
e1.forEach(e2 => {
console.log(e2);
})
});

现场演示:https://stackblitz.com/edit/rxjs-riquzh?devtoolsheight=60

类似于下面的内容,combineLatestAll()只适用于一级映射,这就是它返回错误结果的原因。我更喜欢用mergeMapswitchMap等手动控制可观察的执行

of(5, 15, 25)
.pipe(
mergeMap((v1) =>
of(6, 16, 26).pipe(
mergeMap((v2) => of(7, 17, 27).pipe(map((v3) => [v1, v2, v3])
))
)
)
)
.subscribe(console.log);

根据您的评论,IMO这是一个学习RxJS相对困难的练习。尽管如此,除了@martin提供的解决方案外,您还可以尝试使用reduceObservable<number[][]>0运算符手动设置数组。

注意,reduce((acc, curr) => [...acc, curr], [])toArray()运算符同义。

const { of } = rxjs;
const { concatMap, reduce } = rxjs.operators;
const jsonEditor = document.getElementById('json-editor');
const textContainer = document.getElementById('text-container');
const options = {};
const editor = new JSONEditor(jsonEditor, options);
let s3 = of(5, 15, 25);
let s4 = of(6, 16, 26);
let s5 = of(7, 17, 27);
s3.pipe(
concatMap((v3) =>
s4.pipe(
concatMap((v4) =>
s5.pipe(
reduce((acc, v5, i5) => {
acc[i5] = [v3, v4, v5];
return acc;
}, [])
)
)
)
),
reduce((acc, curr) => [...acc, curr], [])
).subscribe({
next: (response) => editor.set(response),
error: (error) => textContainer.innerHTML = error
});
<link href="https://unpkg.com/jsoneditor@9.4.1/dist/jsoneditor.css" rel="stylesheet" type="text/css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/7.5.5/rxjs.umd.min.js"></script>
<script src="https://unpkg.com/jsoneditor@9.4.1/dist/jsoneditor-minimalist.min.js"></script>
<div id="json-editor" style="width: 100%; height: 100%;"></div>
<span id="text-container"></span>

更新:Typescript

import { of, Observable } from 'rxjs';
import { concatMap, reduce } from 'rxjs';
let s3: Observable<number> = of(5, 15, 25);
let s4: Observable<number> = of(6, 16, 26);
let s5: Observable<number> = of(7, 17, 27);
s3.pipe(
concatMap((v3: number) =>
s4.pipe(
concatMap((v4: number) =>
s5.pipe(
reduce((acc: number[][], v5: number, i5: number) => {
acc[i5] = [v3, v4, v5];
return acc;
}, [])
)
)
)
),
reduce((acc: number[][], curr: number[][]) => [...acc, curr], [])
).subscribe(console.log);

工作示例:Stacklitz

最新更新