过滤嵌套的可观察数组 RxJs Angular
Filter nested observable array RxJs Angular
我正在尝试使用 RxJs 库的组合管道函数中的过滤器函数过滤 angular 中的一些可观察嵌套数组。
问题:
我只想显示具有特定日期给出的调查的类别。
简化情况:
我的 angular 组件有 3 个单选按钮(值 1、2、3)。如果我点击其中之一,它会转到我的 'FilterChanged($event.value)' 函数。在此函数中,我想过滤 api 提供的数据。这个api 首先提供了所有的类别。检索数据后,我想根据单选按钮进行过滤。
这是我从 api:
得到的数据
[
{
"category": "A",
"surveys": [
{
"day": "1",
"answers": [
{
"name": "1",
"value": "a"
},
{
"name": "2",
"value": "b"
},
{
"name": "3",
"value": "c"
}
]
},
{
"day": "2",
"answers": [
{
"name": "1",
"value": "a"
},
{
"name": "2",
"value": "b"
},
{
"name": "3",
"value": "c"
}
]
},
{
"day": "3",
"answers": [
{
"name": "1",
"value": "a"
},
{
"name": "2",
"value": "b"
},
{
"name": "3",
"value": "c"
}
]
}
]
},
{
"category": "B",
"surveys": [
{
"day": "2",
"answers": [
{
"name": "1",
"value": "a"
},
{
"name": "2",
"value": "b"
},
{
"name": "3",
"value": "c"
}
]
},
{
"answers": [
{
"name": "1",
"value": "a"
},
{
"name": "2",
"value": "b"
},
{
"name": "3",
"value": "c"
}
]
},
{
"day": "2",
"answers": [
{
"name": "1",
"value": "a"
},
{
"name": "2",
"value": "b"
},
{
"name": "3",
"value": "c"
}
]
}
]
}
]
如果选择单选按钮 1,我想只显示类别 A 并且只显示它有 1 个调查,因为这是唯一符合过滤器的调查。
为什么这段代码不起作用??更新过滤器在单选框更改事件中被触发。对我来说,这比 reduce with spreader 函数更具可读性。
updateFilter(filterDays : number): void {
var filterDate = this.getFilterDate(filterDays);
this.surveyTypes$ = this.allSurveyTypes$.pipe(map((types) => this.filterSurveyTypes(types, filterDate)));
}
filterSurveyTypes(types : SurveyType[], filterDate : Date) : SurveyType[] {
return types.filter(type => type.surveys.filter(survey => moment(survey.filledInDate).isSameOrAfter(filterDate)).length);
}
还有很多变体,但它似乎不起作用。
我想我不需要地图,因为我没有转换任何数据,所以过滤器应该没问题,但到目前为止对我不起作用。
感谢您的帮助。谢谢
这也适合你:
let teste = [];
allcategories.forEach( category => {
category.surveys.forEach( survey => {
if (survey.day == '1'){
teste.push(survey)
}
})
})
这取决于您如何使用 observable,这里有 2 个示例:
- 如果你想在 属性 中设置类别,而不是可观察的,你必须使用这样的订阅方法:
this.subscription = this.categories$.subscribe({
next: categories => this.categories = categories
});
然后使用this.categories。在这种情况下,不要忘记在销毁组件时调用此 subscription.unsubscribe()。
- 如果您在带有异步管道的组件模板中使用它,它应该可以正常工作。
Remark: an observable is not activated if there is no subscribe (the async pipe does the subscribe and unsubscribe)
我在这里看到的问题是:过滤器函数不同步。这意味着,当您调用第二个过滤器时,第一个过滤器会得到 Promise-like 响应。由于您的代码不是异步的,过滤器将响应所有元素,或 none.
要解决这个问题,您必须将函数声明为异步函数。
以下是有关如何执行此操作的一些示例:
async function awesomeFilter(allcategories){
return await allcategories.filter(category =>
category.surveys.filter(survey => survey.day == '1').length
)
}
survey.day
将是您的嵌套验证;
.length
将 return 到第一个过滤器 0
如果没有找到对应关系或 positive value
如果有,则告诉第一个过滤器对应关系在哪里。
这样我就可以让它工作了。希望对你有所帮助。
不确定您要查找的内容,但似乎您想根据内部数组中的内容过滤外部数组并过滤内部数组,这可以通过 [=12 一次完成=]:
function filterOuterByInner(array, value) {
return array.reduce((acc, v) => {
const tmp = { ...v }; // create shallow copy
tmp.surveys = tmp.surveys.filter(a => a.day === value); // filter surveys array by value
if (tmp.surveys.length)
acc.push(tmp); // add to acc array if any surveys after filter
return acc;
}, []);
}
然后在您的地图中使用它:
this.categories$ = combineLatest(this.allcategories$, this.value$).pipe(map(([categories, val]) => filterOuterByInner(categories, val)));
我正在尝试使用 RxJs 库的组合管道函数中的过滤器函数过滤 angular 中的一些可观察嵌套数组。
问题: 我只想显示具有特定日期给出的调查的类别。
简化情况: 我的 angular 组件有 3 个单选按钮(值 1、2、3)。如果我点击其中之一,它会转到我的 'FilterChanged($event.value)' 函数。在此函数中,我想过滤 api 提供的数据。这个api 首先提供了所有的类别。检索数据后,我想根据单选按钮进行过滤。
这是我从 api:
得到的数据[
{
"category": "A",
"surveys": [
{
"day": "1",
"answers": [
{
"name": "1",
"value": "a"
},
{
"name": "2",
"value": "b"
},
{
"name": "3",
"value": "c"
}
]
},
{
"day": "2",
"answers": [
{
"name": "1",
"value": "a"
},
{
"name": "2",
"value": "b"
},
{
"name": "3",
"value": "c"
}
]
},
{
"day": "3",
"answers": [
{
"name": "1",
"value": "a"
},
{
"name": "2",
"value": "b"
},
{
"name": "3",
"value": "c"
}
]
}
]
},
{
"category": "B",
"surveys": [
{
"day": "2",
"answers": [
{
"name": "1",
"value": "a"
},
{
"name": "2",
"value": "b"
},
{
"name": "3",
"value": "c"
}
]
},
{
"answers": [
{
"name": "1",
"value": "a"
},
{
"name": "2",
"value": "b"
},
{
"name": "3",
"value": "c"
}
]
},
{
"day": "2",
"answers": [
{
"name": "1",
"value": "a"
},
{
"name": "2",
"value": "b"
},
{
"name": "3",
"value": "c"
}
]
}
]
}
]
如果选择单选按钮 1,我想只显示类别 A 并且只显示它有 1 个调查,因为这是唯一符合过滤器的调查。
为什么这段代码不起作用??更新过滤器在单选框更改事件中被触发。对我来说,这比 reduce with spreader 函数更具可读性。
updateFilter(filterDays : number): void {
var filterDate = this.getFilterDate(filterDays);
this.surveyTypes$ = this.allSurveyTypes$.pipe(map((types) => this.filterSurveyTypes(types, filterDate)));
}
filterSurveyTypes(types : SurveyType[], filterDate : Date) : SurveyType[] {
return types.filter(type => type.surveys.filter(survey => moment(survey.filledInDate).isSameOrAfter(filterDate)).length);
}
还有很多变体,但它似乎不起作用。 我想我不需要地图,因为我没有转换任何数据,所以过滤器应该没问题,但到目前为止对我不起作用。
感谢您的帮助。谢谢
这也适合你:
let teste = [];
allcategories.forEach( category => {
category.surveys.forEach( survey => {
if (survey.day == '1'){
teste.push(survey)
}
})
})
这取决于您如何使用 observable,这里有 2 个示例:
- 如果你想在 属性 中设置类别,而不是可观察的,你必须使用这样的订阅方法:
this.subscription = this.categories$.subscribe({
next: categories => this.categories = categories
});
然后使用this.categories。在这种情况下,不要忘记在销毁组件时调用此 subscription.unsubscribe()。
- 如果您在带有异步管道的组件模板中使用它,它应该可以正常工作。
Remark: an observable is not activated if there is no subscribe (the async pipe does the subscribe and unsubscribe)
我在这里看到的问题是:过滤器函数不同步。这意味着,当您调用第二个过滤器时,第一个过滤器会得到 Promise-like 响应。由于您的代码不是异步的,过滤器将响应所有元素,或 none.
要解决这个问题,您必须将函数声明为异步函数。
以下是有关如何执行此操作的一些示例:
async function awesomeFilter(allcategories){
return await allcategories.filter(category =>
category.surveys.filter(survey => survey.day == '1').length
)
}
survey.day
将是您的嵌套验证;
.length
将 return 到第一个过滤器 0
如果没有找到对应关系或 positive value
如果有,则告诉第一个过滤器对应关系在哪里。
这样我就可以让它工作了。希望对你有所帮助。
不确定您要查找的内容,但似乎您想根据内部数组中的内容过滤外部数组并过滤内部数组,这可以通过 [=12 一次完成=]:
function filterOuterByInner(array, value) {
return array.reduce((acc, v) => {
const tmp = { ...v }; // create shallow copy
tmp.surveys = tmp.surveys.filter(a => a.day === value); // filter surveys array by value
if (tmp.surveys.length)
acc.push(tmp); // add to acc array if any surveys after filter
return acc;
}, []);
}
然后在您的地图中使用它:
this.categories$ = combineLatest(this.allcategories$, this.value$).pipe(map(([categories, val]) => filterOuterByInner(categories, val)));