帖子的 RX JS 聚合
rx js aggregation for posts
我正在尝试使用 rx for js 来理解函数式编程。
我有一个发出"post"对象的 Rx.Observable:
每个帖子看起来像这样:
{
title: "sometitle",
author: "someauthor"
text: "sometext",
date: "somedate",
tags: ['tag1', 'tag2', ..., 'tagN']
}
我想将该序列转换为发出以下信号的序列:
{
tag: 'tagname',
postCount: n
}
这是我到目前为止所拥有的:
function tags(post) {
return post
.tags
.map(function(tag) { return { 'tag': tag, 'count': 1});
}
posts
.flatMap(tags)
.groupBy(function(tagged) { return tagged.tag })
. // don't know how to continue
正如我之前所说,我的目标是创建一个为每个标签发出{tag: 'tagname', postCount: n }
的序列/可观察量
提前感谢
编辑:
我忘了提到我正在寻找"面向节点"的答案。
这就是我目前所拥有的。它有效,但我不确定{ ..., count: 1 }
部分。我正在寻找一个更"优雅"的解决方案。
posts
.flatMap(tags)
.map((tag) => {return {name: tag, count: 1}})
.groupBy((tagcount) => {return tagcount.name})
.flatMap((taggroup) => {return taggroup.reduce((a,x) => {return {tag: x.name, count: (a.count + x.count)}})})
它会是这样的:
// sequesnce of posts sequence with 10ms interval
var posts = Rx.Observable
.fromArray([
{ tags: ['tag1', 'tag2'] },
{ tags: ['tag1', 'tag3'] },
{ tags: ['tag1'] },
{ tags: ['tag1', 'tag2', 'tag3'] }
])
.zip(Rx.Observable.interval(10), Rx.helpers.identity)
.do(logger('post:'));
// sequence of post counts by tags, and count changes
var tagsCountChanges = posts.scan(
function (acc, post) {
var counts = acc.counts;
var changes = [];
post.tags.forEach(function (tag) {
counts[tag] = (counts[tag] || 0) + 1;
changes.push({ tag: tag, postsCount: counts[tag] });
});
return { counts, changes };
}, { counts: {}, changes: [] })
.map(acc => acc.changes)
.do(logger('tagsCountChanges:'));
var tagCountUpdates = tagsCountChanges
.concatMap(function (changes) {
return Rx.Observable
.fromArray(changes);
});
tagCountUpdates
.forEach(logger('tagPostCounts:'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/4.1.0/rx.all.js"></script>
<pre id="log"></pre>
<script>
var log = document.getElementById('log');
function logger(label) {
return function(item) {
log.appendChild(document.createTextNode(label + ' ' + JSON.stringify(item, null, 2) + ''n'));
};
}
</script>
更新(响应编辑1):
它也将在节点中工作:)您也可以删除记录器和帖子序列的间隔 - 它只是为了在浏览器中运行代码段时显示带有中间可观察量的良好项目日志。
我不确定
{ ..., count: 1 }
部分。 我正在寻找一个更"优雅"的解决方案。
实际上,您可以完全删除{ ..., count: 1 }
部分:
posts
.flatMap(post => post.tags)
.groupBy(Rx.helpers.identity)
.flatMap(taggroup$ =>
taggroup$.reduce((acc,tag) => {return {tag, count: acc.count+1}}, {count:0})
)
关于优雅:我喜欢你的解决方案 - 我认为它比我的更有表现力,更简单。但是,我的解决方案在较大的标签计数下性能会更高(因为它不会为每个标签创建内部可观察量)。
此外,我的解决方案与您的解决方案略有不同 - 它将发出标签计数更改流,而不仅仅是最终计数(帖子流完成后)。
可以轻松修改您的解决方案以达到相同的结果 - 只需将reduce
替换为scan
即可。
签证反之亦然 - 如果只需要总数,我的解决方案可以简化很多:
posts.reduce(
(counts, post) => {
post.tags.forEach(tag => {
counts[tag] = (counts[tag] || 0) + 1;
});
return counts;
}, {})
.flatMap(counts =>
Object.keys(counts).map(
tag => ({tag, count: counts[tag]})
)
)
相关文章:
- 可以't让我的if语句处理js中的html表单输入
- 使用agility.js进行页面布局和合成
- 使用Clipboard.js复制span文本
- 使用JS如何动态更改显示的html文件中的文本背景颜色
- 强制模板刷新ember.js
- 如何编写HTML输入的JS内联
- Angular JS IE9 Hashbang url rewriting
- 聚合Sails.JS/Waterline中的嵌套模型数据
- 帖子的 RX JS 聚合
- 如何在mongoose/node.js中的聚合查询中使用变量
- 用于定期聚合数据并使用 Node.js 为其提供服务的基础架构
- 如何在 Mean.io 上聚合 JS 资产
- TypeError:无法调用方法'toArray'在node.js中聚合mongo时未定义的
- 聚合数据绑定和Immutable.js
- 使用Underscore Js聚合嵌套数据
- 在聚合js中的动态元素上添加事件侦听器
- MongoDB与node.js,我不知道如何排序组聚合
- 使用Underscore js过滤、分组和聚合数据
- 使用Underscore JS对JSON数组进行分组和聚合
- 我如何使用pubsub与backbone.js聚合事件数据