以下代码:
const Rx = require('rx');
const gameRowObservable = Rx.Observable.fromArray([{
game_id: 1,
game_name: "game one",
}, {
game_id: 2,
game_name: "game two",
}]);
const playerRowObservable = Rx.Observable.fromArray([{
game_id: 1,
player_id: 1,
player_name: "player one",
}, {
game_id: 1,
player_id: 2,
player_name: "player two",
}, {
game_id: 2,
player_id: 3,
player_name: "player three",
}, {
game_id: 2,
player_id: 4,
player_name: "player four",
}]);
const rowObservable = gameRowObservable.
groupJoin(
playerRowObservable,
gameRow => Rx.Observable.return(gameRow.game_id),
playerRow => Rx.Observable.return(playerRow.game_id),
(gameRow, playerGroup) => playerGroup.toArray().map(playerGroup => Object.assign(gameRow, {
player_list: playerGroup
}))
).mergeAll();
rowObservable.subscribe(row => console.log(row));
产生以下结果:
{ game_id: 1, game_name: 'game one', player_list: [] }
{ game_id: 2, game_name: 'game two', player_list: [] }
我想得到这个结果:
[{
game_id: 1,
game_name: "game one",
player_list: [{
game_id: 1,
player_id: 1,
player_name: "player one",
}, {
game_id: 1,
player_id: 2,
player_name: "player two",
}]
}, {
game_id: 2,
game_name: "game two",
player_list: [{
game_id: 2,
player_id: 3,
player_name: "player three",
}, {
game_id: 2,
player_id: 4,
player_name: "player four",
}]
}]
所以我基本上希望每场比赛的球员都是阵列属性。我做错了什么?
答案 0 :(得分:1)
我无法提供有效的解决方案,但我希望我能帮助您走上正确的道路。
正如您在groupJoin的文档中所看到的,第二个和第三个参数用于确定要分组的持续时间而不是属性值。
你实际上是通过重叠进行分组,即从gameRowA的发射开始,在发出下一个gameRow之前发出的任何playerRows都与gameRowA分组。由于您不希望任何花哨的分组,您的持续时间选择器只是您的源可观察量。见jsbin
const rowObservable = gameRowObservable.
groupJoin(
playerRowObservable,
gameRow => gameRowObservable,
playerRow => playerRowObservable,
(gameRow, playerGroup) => playerGroup.toArray().map(playerGroup => Object.assign(gameRow, {
player_list: playerGroup
}))
).mergeAll();
rowObservable.subscribe(row => console.log(row));
答案 1 :(得分:0)
如果您无法根据之前给出的示例(http://rxwiki.wikidot.com/101samples#toc39)设置代码,则此处为jsfiddle(http://jsfiddle.net/t2bjy03p/2/):
var gameRowObservable
= Rx.Observable.fromArray([
{game_id : 1, game_name : "game one" },
{game_id : 2, game_name : "game two" }
]);
var playerRowObservable
= Rx.Observable.fromArray([
{game_id : 1, player_id : 1, player_name : "player one"},
{ game_id : 1, player_id : 2, player_name : "player two"},
{game_id : 2, player_id : 3, player_name : "player three"},
{game_id : 2, player_id : 4, player_name : "player four"}
]);
var rowObservable = gameRowObservable.
groupJoin(
playerRowObservable,
function () {return Rx.Observable.merge(gameRowObservable, playerRowObservable).last()},
function () {return Rx.Observable.never()},
function ( gameRow, playerRowObservable ) {
return playerRowObservable
.filter(function ( playerRow ) {
return playerRow.game_id === gameRow.game_id
})
.toArray()
.map(function(player_list){return Object.assign(gameRow, {
player_list: player_list})})
})
.mergeAll();
rowObservable.subscribe(function ( row ) {console.log(row)});
在控制台中,您应该看到确切的预期输出。
一些解释:
groupJoin
根据持续时间选择器进行分组。对于这个复杂的运算符,标准文档非常密集,我认为这里更清楚:http://reactivex.io/documentation/operators/join.html GroupJoinOp_Normal_I
)player_list
的对象中。groupJoin
返回的observable将发出一个只有一个元素的observable,该元素在发出该元素后很快就会完成。mergeAll
展平所观察到的可观察物可能会稍微短一些。我没有太多时间去调查,但是如果你这样做,请在这里发布结果。我还没有看到很多关于这个运营商的问题,所以任何信息都是受欢迎的。
答案 2 :(得分:0)
暂时我使用非rx解决方案。如果我想要的东西不可能与RxJS一起使用,那么我觉得持续时间实际上是指持续时间。
仅供参考我现在使用的解决方案有点类似:
const gameRows = [{
game_id: 1,
game_name: "game one",
}, {
game_id: 2,
game_name: "game two",
}];
const playerRows = [{
game_id: 1,
player_id: 1,
player_name: "player one",
}, {
game_id: 1,
player_id: 2,
player_name: "player two",
}, {
game_id: 2,
player_id: 3,
player_name: "player three",
}, {
game_id: 2,
player_id: 4,
player_name: "player four",
}];
gameRows.sort((a, b) => a.game_id - b.game_id);
playerRows.sort((a, b) => a.game_id - b.game_id);
/*
in the thing I am building, I get the two lists from a database and sort them
in the database!
*/
const playerRowCount = playerRows.length;
var playerRowIndex = 0;
const rows = gameRows.map(gameRow => {
const player_list = [];
while (playerRowIndex < playerRowCount && playerRows[playerRowIndex].game_id === gameRow.game_id) {
player_list.push(playerRows[playerRowIndex]);
playerRowIndex++;
}
return Object.assign({
player_list
}, gameRow);
});
rows.forEach(row => console.log(row));
如果存在有效的RxJS解决方案,我仍然很好奇。