如何通过密钥对活动的observable进行分区并将分区合并到组中,组合该组的每个分区的最后一个元素

时间:2016-01-23 21:15:21

标签: system.reactive reactive-programming

我有一个热点可观察的项目序列,这些项目具有标识特定子流的键。我有兴趣将这些M流映射到N,其中N

在下面的示例中,我们有四个水果的引用序列。我希望通过水果类型(Apple或Pear)将这些流映射成两个。对于每个小组,我想收集每个水果的最后一个已知报价。

class Input {
    public string ProductID {get;set;}
    public string ProductType {get;set;}
    public int    Price {get;set;}
}

class Output {
    public string  ProductType {get;set;}
    public Input[] Underlining {get;set;}
}

var obs = new List<Input> {
    new Input { ProductID = "Stark",    ProductType = "Apple", Price = 21 },
    new Input { ProductID = "Jonagold", ProductType = "Apple", Price = 12 },
    new Input { ProductID = "Williams", ProductType = "Pear",  Price = 33 },
    new Input { ProductID = "Beth",     ProductType = "Pear",  Price = 22 },
    new Input { ProductID = "Stark",    ProductType = "Apple", Price = 43 },
    new Input { ProductID = "Williams", ProductType = "Pear",  Price = 55 },
    new Input { ProductID = "Beth",     ProductType = "Pear",  Price = 66 },
    new Input { ProductID = "Jonagold", ProductType = "Apple", Price = 77 },
    new Input { ProductID = "Jonagold", ProductType = "Apple", Price = 25 },
    new Input { ProductID = "Williams", ProductType = "Pear",  Price = 77 },
    new Input { ProductID = "Beth",     ProductType = "Pear",  Price = 13 },
    new Input { ProductID = "Stark",    ProductType = "Apple", Price = 21 },
}.ToObservable();

IObservable<Output> result = obs.GroupBy ... Select ... Concat ... ; // I'm a bit loss here 


result.Dump();

预期结果:

{ ProductType = "Apple", Underlining = [{ ProductID = "Stark",    Price = 21 }] }
{ ProductType = "Apple", Underlining = [{ ProductID = "Stark",    Price = 21 },     { ProductID = "Jonagold", Price = 12 }] }
{ ProductType = "Pear",  Underlining = [{ ProductID = "Williams", Price = 23 }] }
{ ProductType = "Pear",  Underlining = [{ ProductID = "Williams", Price = 23 },     { ProductID = "Beth",     Price = 22 }] }
{ ProductType = "Apple", Underlining = [{ ProductID = "Stark",    Price = **43** }, { ProductID = "Jonagold", Price = 12 }] }
{ ProductType = "Pear",  Underlining = [{ ProductID = "Williams", Price = **55** }, { ProductID = "Beth",     Price = 22 }] }
{ ProductType = "Pear",  Underlining = [{ ProductID = "Williams", Price = 55 },     { ProductID = "Beth",     Price = **66** }] }
{ ProductType = "Apple", Underlining = [{ ProductID = "Stark",    Price = 43 },     { ProductID = "Jonagold", Price = **77** }] }
{ ProductType = "Apple", Underlining = [{ ProductID = "Stark",    Price = 43 },     { ProductID = "Jonagold", Price = **25** }] }
{ ProductType = "Pear",  Underlining = [{ ProductID = "Williams", Price = **77** }, { ProductID = "Beth",     Price = 66 }] }
{ ProductType = "Pear",  Underlining = [{ ProductID = "Williams", Price = 77 },     { ProductID = "Beth",     Price = **13** }] }
{ ProductType = "Apple", Underlining = [{ ProductID = "Stark",    Price = **21** }, { ProductID = "Jonagold", Price = 25 }] }

1 个答案:

答案 0 :(得分:2)

我认为这就是你想要的:

var app = angular.module('app',[])
  .controller('AppCtrl', function($scope) {});

我使用var outputs = obs .GroupBy(x => x.ProductType) .Select(xs => xs .Scan( new Dictionary<string, Input>(), (d, x) => { d[x.ProductID] = x; return d; }) .Select(x => new Output() { ProductType = xs.Key, Underlining = x.Values.ToArray(), })) .Merge(); 获取以下输出来测试它:

outputs.Select(x => $"{{ ProductType = \"{x.ProductType}\", Underlining = [{String.Join(", ", x.Underlining.Select(y => $"{{ ProductID = \"{y.ProductID}\", Price = {y.Price} }}"))}] }}")