首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >scan、groupjoin或groupjoin直到?

scan、groupjoin或groupjoin直到?
EN

Stack Overflow用户
提问于 2016-07-14 04:46:58
回答 2查看 128关注 0票数 0

假设有一些问题和答案,如下图所示。答案总是与最近的问题相对应。

代码语言:javascript
复制
QUESTIONS: A     B      C        D
ANSWERS:     1 2         3 4 5    6

打印出相应的问题和答案的最佳方法是什么?下面是我使用Scan得到的一个解决方案。但是,我想知道是否有更直观的方式使用GroupJoin来完成此任务。我试过GroupJoin,但不能让它工作。我也很好奇GroupBy或GroupByUntil是否是合适的选项(但也无法让它们工作)。最后,这是我需要使用发布的情况吗?

代码语言:javascript
复制
static void Main(string[] args) {
    var questions = new Subject<string>();
    var answers = new Subject<int>();
    var results = Observable
        .CombineLatest(
            questions,
            answers.StartWith(-1),
            (q, a) => new { Question = q, Answer = a })
        .Scan((a, b) =>
            (a.Question == b.Question)
            ? b
            : new { Question = b.Question, Answer = -1 });

    results.Subscribe(i => Console.WriteLine((i.Answer == -1) ? i.Question : $"  {i.Answer}"));

    questions.OnNext("A");
    answers.OnNext(1);
    answers.OnNext(2);
    questions.OnNext("B");
    questions.OnNext("C");
    answers.OnNext(3);
    answers.OnNext(4);
    answers.OnNext(5);
    questions.OnNext("D");
    answers.OnNext(6);

    Console.ReadLine();
}

预期输出如下:

代码语言:javascript
复制
A
  1
  2
B
C
  3
  4
  5
D
  6

我想得越多,这个特性就越像数据库世界中的LeftJoin行为。我也可以使用如下所示的代码让它正常工作。由于某些原因,它在控制台应用程序中不起作用。当我用我自己的Versioned函数(分配递增的长值)替换时间戳函数时,它工作得很好。

代码语言:javascript
复制
var results = Observable
    .CombineLatest(questions.Timestamp(), answers.StartWith(-1).Timestamp(), (q, a) => new { Question = q, Answer = a })
    .Select(i => (i.Answer.Timestamp > i.Question.Timestamp)
        ? new { Question = i.Question.Value, Answer = i.Answer.Value }
        : new { Question = i.Question.Value, Answer = -1 });
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-07-14 05:54:53

下面是如何使用GroupJoin实现这一点

代码语言:javascript
复制
var results = questions.GroupJoin(answers,
    s => questions,
    s => Observable.Empty<int>(),
    (q, a) => new { Question = q, Answers = a });

results2
    .Subscribe(i => 
    {
        Console.WriteLine(string.Format("{0}", i.Question));
        i.Answers.Subscribe(a => Console.WriteLine("  {0}", a));
    });

这将产生与您的代码相同的输出。

票数 1
EN

Stack Overflow用户

发布于 2016-07-14 16:22:28

也许把这事说得更简单些。我认为最简单的答案就是使用merge并将两个序列投影到一个公共类型。只要看看预期的输出,你就会发现它只是一个合并的序列。

代码语言:javascript
复制
var questions = new Subject<string>();
var answers = new Subject<int>();
var Qs = questions.Select(q => new { Question = q, Answer = -1});
var As = answers.Select(a => new { Question = (string)null, Answer = a});
Observable.Merge(Qs,As)
    .Subscribe(i => Console.WriteLine((i.Answer == -1) ? i.Question : $"  {i.Answer}"));

questions.OnNext("A");
answers.OnNext(1);
answers.OnNext(2);
questions.OnNext("B");
questions.OnNext("C");
answers.OnNext(3);
answers.OnNext(4);
answers.OnNext(5);
questions.OnNext("D");
answers.OnNext(6);

结果

代码语言:javascript
复制
A
  1
  2
B
C
  3
  4
  5
D
  6
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38361389

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档