在Angular/TS中,如何构造Observable以搜索对象树-键、值类型?
我有一个带有两个属性k,v(key,value)的简单接口 这是相同类型的各种嵌套对象的基础-KV, 其中v:可能包含KV的嵌套子对象,并最终到达树的最后一个/叶对象 式中,v:为串-非KV型 示例:(在本例中,层次结构颠倒过来-最后一个表位于顶部-包含v(值)为字符串的条目。以下节点为父节点,底部节点为根节点在Angular/TS中,如何构造Observable以搜索对象树-键、值类型?,angular,typescript,observable,Angular,Typescript,Observable,我有一个带有两个属性k,v(key,value)的简单接口 这是相同类型的各种嵌套对象的基础-KV, 其中v:可能包含KV的嵌套子对象,并最终到达树的最后一个/叶对象 式中,v:为串-非KV型 示例:(在本例中,层次结构颠倒过来-最后一个表位于顶部-包含v(值)为字符串的条目。以下节点为父节点,底部节点为根节点 const tableC2: KV[] = [ { k: 'TXT1', v: 'text 1'}, { k: 'TXT2', v: 'text 2'}, {
const tableC2: KV[] = [
{ k: 'TXT1', v: 'text 1'},
{ k: 'TXT2', v: 'text 2'},
{ k: 'TXT3', v: 'text 3'},
....
];
const tableB1: KV[] = [
{ k: 'C1', v: tableC1},
{ k: 'C2', v: tableC2}, // <--- tableC2 above
{ k: 'C3', v: tableC3},
....
];
const tableA: KV[] = [
{ k: 'A1', v: tableA1},
{ k: 'A2', v: tableA2},
{ k: 'B1', v: tableB1}, // <--- tableB1 above
....
]
设置async/Observable以搜索树层次结构中的键(例如键='TXT3'并获取其v/值-'text 3',以便我们可以使用| async管道将可观测值放置在角度模板中)的最有效方法是什么
在常规/同步方法中,我有如下内容:
private findText(nodes: KV[], key: string): any {
let d: KV[];
for (let n of nodes) {
// navigate to last child node, where v
// is no longer of another KV (k,v) type
while(n.hasOwnProperty('k') && n.hasOwnProperty('v')) {
d = n.v;
n = n.v;
}
let result = d.find(e => e.k === key);
if (result) {
return result.v;
}
}
return undefined;
}
这样行
我们如何使这个函数异步
类似这样(但这只是一个想法,我在更复杂的层面上迷失了方向):
公共findText(节点$:可观察,键:字符串):可观察{
返回节点$.pipe(开关映射(e=>
e、 forEach(n=>
n、 v.filter(v=>(!v.hasOwnProperty('k')&&&!v.hasOwnProperty('v'))
.filter(t=>(t==key))
.map(r=>r.v));
}
您仍然可以使用同步方法
public findText(nodes$: Observable<KV[]>, key: string): Observable<any> {
return nodes$.pipe(map(nodes => findTextSync(nodes, key)));
}
公共findText(节点$:可观察,键:字符串):可观察{
返回节点$.pipe(map(nodes=>findTextSync(nodes,key));
}
为什么这是一个开关映射而不仅仅是一个映射?我不认为函数的同步版本适用于嵌套级别,除非它是递归的。@MoxxiManagarm的解决方案可以工作,如果你纠正你的同步函数当然,这是一种方法。但我希望用“优雅的”/“lambda”风格的方法。
private findText(nodes: KV[], key: string): any {
let d: KV[];
for (let n of nodes) {
// navigate to last child node, where v
// is no longer of another KV (k,v) type
while(n.hasOwnProperty('k') && n.hasOwnProperty('v')) {
d = n.v;
n = n.v;
}
let result = d.find(e => e.k === key);
if (result) {
return result.v;
}
}
return undefined;
}
public findText(nodes$: Observable<KV[]>, key: string): Observable<any> {
return nodes$.pipe(switchMap(e =>
e.forEach(n =>
n.v.filter(v => ( ! v.hasOwnProperty('k') && ! v.hasOwnProperty('v')))
.filter(t => (t === key))
.map(r => r.v))));
}
public findText(nodes$: Observable<KV[]>, key: string): Observable<any> {
return nodes$.pipe(map(nodes => findTextSync(nodes, key)));
}