我想从过去7天内质量评级最高的Firebase数据库中返回一个对象。我使用以下的Typescript代码,首先查询过去七天内创建的所有线程,然后,在quality
提取具有最高值的线程。理想情况下,我可以'#34;转换" results
可观察到forEach语句的最终迭代对象。
highestWeek: Number = 0;
...
getWeeksBest(): Observable<any> {
let now = Date.now() / 1000;
let results = this.af.database.list('/threads', {
query: {
orderByChild: 'created',
startAt: now - 604800 //One week ago
}
})
.map(results => {
results.forEach(result => {
if (result.quality > this.highestWeek) {
console.log(result) //Logs next highest quality thread
this.highestWeek = result.quality
}
})
})
results.subscribe(results => console.log(results)) //Undefined
return results //Undefined
}
答案 0 :(得分:1)
所以问题可能就是你在undefined
变量的subscribe(...)
回调中获得results
的原因。
在.map()
中,您使用短箭头语法创建代码块,但这意味着您必须使用return
语句。
.map(results => {
results.forEach(result => {
if (result.quality > this.highestWeek) {
console.log(result) //Logs next highest quality thread
this.highestWeek = result.quality
}
});
return results;
})
在您的情况下,我最好使用.do()
运算符而不是.map()
。
在getWeeksBest()
结束时,您将返回Observable,因此最后一行肯定不会返回undefined
。
getWeeksBest(): Observable<any> {
let now = Date.now() / 1000;
let results = this.af.database.list('/threads', {
...
});
return results;
}
答案 1 :(得分:1)
return
语句。但请记住,Array.forEach始终返回undefined
。因此,在您的情况下,您可以使用Array.map
。
但总的来说,我会建议这样的事情:
getAllThreads$(): Observable<any[]> {
let now = Date.now() / 1000;
return this.af.database.list('/threads', {
query: {
orderByChild: 'created',
startAt: now - 604800 //One week ago
}
})
}
getWeeksBest$():Observable<number>{
return this.getAllThreads$().map(threads => Array.isArray(threads )? threads.reduce((highestQuality, thread) => {
let currentQuality = thread? thread.quality: 0;
return currentQuality > highestQuality? currentQuality: highestQuality;
}, 0): 0);
}
在您的类构造函数中的某处只订阅getWeeksBest$
答案 2 :(得分:1)
RxJS为众多运营商提供数据转换。在您的情况下,您想要检索具有最高quality
值的对象,因此我们可以使用 reduce 运算符来应用maxBy()
函数。
const weeks = [
{
quality: 1
},
{
quality: 15
},
{
quality: 5
},
{
quality: 8
}
];
//maxBy stateless function (you can see a currified function)
const maxBy = (prop) => (a, b) => a[prop] > b[prop] ? a : b;
//Fetch data and apply the maxBy when the reduce is perform over the collection
function fetchData() {
//You can perform some async actions
return Rx
.Observable
.from(weeks)
.reduce(maxBy('quality'), 0);
}
fetchData().subscribe(x => console.log(x));
请随意查看Plunker
上的示例答案 3 :(得分:1)
如果要返回在上周发出质量最高的线程的observable,则传递给df1 %>% mutate(X = rowSums(.[-1] == 1))
# Cluster a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 X
#1 C1 0 1 1 1 0 1 1 1 1 1 1 9
#2 C2 0 1 1 1 0 1 1 1 1 1 1 9
#3 C3 0 1 0 0 0 0 1 0 0 0 0 2
#4 C4 0 1 1 1 0 1 1 1 1 1 1 9
#5 C5 0 1 1 1 0 1 1 1 1 1 1 9
运算符的函数需要返回一个值(如其他答案中所述)。
此外,如果没有线程,您需要决定应该预期的行为。结果可观察结果是否为空?或者它应该发出map
?
最好避免内部订阅 - 您将对每次通话进行额外订阅,并且所述订阅永远不会取消订阅。并且最好避免副作用,因为最高质量将由发出的线程提供。
你可以做这样的事情,而不是:
null
如果您想在没有线程的情况下发出getWeeksBest(): Observable<any> {
let now = Date.now() / 1000;
let best = this.af.database.list('/threads', {
query: {
orderByChild: 'created',
startAt: now - 604800 //One week ago
}
})
// Filter out empty lists of threads, so that the resultant
// observable emits nothing if there are no threads:
.filter(threads => threads.length > 0)
// Use Array.prototype.reduce to return the thread with the
// highest quality:
.map(threads => threads.reduce(
(acc, thread) => thread.quality > acc.quality ? thread : acc
));
return best;
}
,请移除null
并将filter
更改为:
map