如何获得的总和"最后"小数将N热观测&LT的物品;实例? [英] How to get Sum of "last" items of N hot Observable<decimal> instances?

查看:147
本文介绍了如何获得的总和"最后"小数将N热观测&LT的物品;实例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑:在2013年9月15日 - 我描述我的方案进一步分成步骤来帮助大家理解我的处境要好。增加了对下载整个应用程序太源。如果你想跳到原来的问题,向下滚动到最后的标题。请让我知道这个问题。谢谢



摘要



阿拉斯加州首府朱诺有一个AST(阿拉斯加州警官)总部大楼,他们想显示大屏幕,自动显示和更新的一个数字。这个数字被称为(犯罪智商指数)或CQI



CQI基本上是一个计算的数字显示状态的当前犯罪形势...



它是如何计算的?



运行画面的节目是不断地通过热接收CrimeReport对象.NET WPF应用程序的IObservable流。



CQI是每个城市计算,然后将所有城市中的SUM()取被称为美国CQI
以下是计算的步骤国家CQI



步骤1 - 接收犯罪数据



CrimeReport每次都​​发送到.NET应用程序的罪行报道。它具有以下部件



日期时间的犯罪



的 - 管辖权的市/县



SeverityLevel 的 - 严重/不严肃



EstimatedSolveTime 的 - 估计天数AST决定,将采取破案的。



因此​​,在此步骤中,我们订阅的IObservable和创建MainViewModel的实例



 的IObservable< CrimeReport> reportSource = mainSource.Publish(); 
MainVM =新MainViewModel(reportSource);
reportSource.Connect();



步骤2 - 集团按城市,做每个城市的数学



当你收到报告,这组由城市如此

  VAR城市= reportSource.GroupBy(K => ; k.City)
。选择(G =>新建CityDto(g.Key,G);

CityDto是一个DTO类,它的所有报告当前城市并计算出城市的CQI。



市的CQI的计算由下列公式​​进行




如果总数严重犯罪非严重罪行总数的比例小于1



然后



估计解决时间



市的CQI =比x最低

其他



估计解决时间城市的CQI =比X最大




下面是CityDto

 内部类CityDto 
{
的类定义公共字符串CITYNAME {搞定;组; }
公众的IObservable<&小数GT; CityCqi {搞定;设置;}

公共CityDto(字符串的cityName,与的IObservable LT; CrimeReport> cityReports)
{
CITYNAME =的cityName;
//获取所有严重和不严重的罪行
//
VAR totalSeriousCrimes = cityReports.Where(C => c.Severity == CrimeSeverity.Serious)
.Scan( 0,(对,_)=指p ++);
变种totalnonSeriousCrimes = cityReports.Where(C => c.Severity == CrimeSeverity.NonSerious)
.Scan(0,(对,_)=指p ++);

//获取比
//
变种比= Observable.CombineLatest(totalSeriousCrimes,totalnonSeriousCrimes,
(S,N)=> N == 0 ?s:S / N); // Avoding DivideByZero这里

//获取最小和最大估计解决时间
//
VAR minEstimatedSolveTime = cityReports.Select(C => c.EstimatedSolveTime)
.Scan(5000,(p,N)=将N&下; p N:p);
变种maxEstimatedSolveTime = cityReports.Select(C => c.EstimatedSolveTime)
.Scan(0,(P,N)=将N指p N:ΔP);

//时间城市的CQI
//
CityCqi = Observable.CombineLatest(比,minEstimatedSolveTime,maxEstimatedSolveTime,(R,N,X)=>为r ?1.0 R * N:R * M);
}
}

现在,我们有市DTO对象保持城市的CQI值并通过的IObservable露出了现场CQI,阿拉斯加州州首府想总结()所有城市'CQI将其显示为阿拉斯加的CQI,并显示其生活画面,并​​在市/县随时随地报道每次作案参加CQI上方案应该对国家的CQI了立竿见影的效果。



步骤3 - 卷起城市的数据状态



现在我们要计算整个国家的CQI这是大屏幕,我们呼吁国家视图模型MainViewModel

 内部的实时更新类MainViewModel 
{
公共MainViewModel(的IObservable< CrimeReport> mainReport)
{
///这里是片段在步骤2中
// $ b $也提到b VAR城市= mainReport.GroupBy(K => k.City)
。选择(G =>新建CityDto(g.Key,G));

/////牛逼他/////是//// ////在哪里我/// ///上午卡住
//
变种allCqis = cities.Select(C => c.CityCqi); //给你的IObservable<&的IObservable LT;十进制>> ,

///需要使用最新的观察到每一个在allCqi,总结起来
////我该怎么办呢?
}
}



限制




  • 未在阿拉斯加所有城市目前正在参与国家的CQI项目,但城市招收一天一天,所以我不能有列表和不分招生将所有的城市或者是不实际的。所以这是的IObservable其中仅维护这些城市不仅参与而且还已将至少一个CrimeReport对象。



完整的源代码



来源可以通过点击这里

最初问的问题



我有一个观察的热点多热观测的..

 的IObservable<&的IObservable LT;十进制>> 

我想一个可观察的认购将仍然保持其观察员告知所有最新的总和十进制数从内所有观测。



我怎样才能做到这一点?我试图CombineLatest(...),但无法得到它的权利。



感谢


解决方案

借助 RXX 库有过载 CombineLatest()这需要一个的IObservable<&的IObservable LT; T>> 。如果您使用此重载,那么解决方案很简单:

  VAR运行总和= allCqis 
。选择(CQI => ; cqi.StartWith(0))//启动每个内部序列了与0
.CombineLatest()//产生的IObservable<&IList的LT;十进制>>
。选择(的CQI = GT; cqis.Sum()); // LINQ运营商总和(IEnumerable的<十进制>)



查看源代码 Rxx.CombineLatest 会怎么看这个问题的。


引擎盖下解决是有益的

EDIT: On 09/15/2013 - I am describing my scenario further broken into steps to help everybody understand my situation better. Added the source for whole application for download too. If you want to jump to the original question, scroll down to the last heading. Please let me know the questions. Thanks

Summary

Alaska state Capital Juneau has a AST (Alaska State Trooper) headquarters building where they would like to show a large screen with a single number displayed and updated automatically. That number is called (Crime Quotient Index) or CQI

CQI is basically a calculated number to show the current crime situation of the state...

How it is calculated?

The program that runs the screen is a .NET WPF Application that is constantly receiving CrimeReport objects through a Hot IObservable stream.

CQI is calculated per city and then a Sum() for all cities is taken which is called States CQI Here are the steps of calculating the State CQI

Step 1 - Receive crime data

CrimeReport is sent to the .NET Application each time a crime is reported. It has the following components

DateTime of the crime

City - City/County of Jurisdiction

SeverityLevel - Serious/NonSerious

EstimatedSolveTime - Estimated number of days AST determines it would take to solve the crime.

So in this step, we subscribe to the IObservable and create instance of MainViewModel

IObservable<CrimeReport> reportSource = mainSource.Publish();
  MainVM = new MainViewModel(reportSource);
reportSource.Connect();

Step 2 - Group by city and do maths per city

As you receive the Report, group it by city so

var cities = reportSource.GroupBy(k => k.City)
                  .Select(g => new CityDto(g.Key, g);

CityDto is a DTO class that takes all its report for current city and calculates the City's CQI.

The calculation of City's CQI is done by the following formula

if Ratio of Total number serious crimes to Total number of Non serious crimes is less than 1

then

City's CQI = Ratio x Minimum of Estimated Solve time

else

City's CQI = Ratio x Maximum Estimated Solve time

Here is class definition of CityDto

internal class CityDto 
{
 public string CityName { get; set; }
 public IObservable<decimal> CityCqi {get; set;}

 public CityDto(string cityName, IObservable<CrimeReport> cityReports)
 {
   CityName = cityName;
   // Get all serious and non serious crimes
   //
     var totalSeriousCrimes = cityReports.Where(c => c.Severity == CrimeSeverity.Serious)
     .Scan(0, (p, _) => p++);
     var totalnonSeriousCrimes = cityReports.Where(c => c.Severity == CrimeSeverity.NonSerious)
     .Scan(0, (p, _) => p++);

     // Get the ratio
     //
     var ratio = Observable.CombineLatest(totalSeriousCrimes, totalnonSeriousCrimes, 
                   (s, n) => n ==  0? s : s/n); // Avoding DivideByZero here

     // Get the minimum and maximum estimated solve time
     //
       var minEstimatedSolveTime = cityReports.Select(c => c.EstimatedSolveTime) 
                     .Scan(5000, (p, n) => n < p? n : p);
       var maxEstimatedSolveTime = cityReports.Select(c=>c.EstimatedSolveTime)
                     .Scan(0, (p, n) => n > p? n : p);

    //Time for the City's CQI
    // 
      CityCqi = Observable.CombineLatest(ratio, minEstimatedSolveTime, maxEstimatedSolveTime, (r, n, x) => r < 1.0? r * n : r * m);
 }
}

Now that we have City DTO objects maintaining City's CQI values and exposing that live CQI through an IObservable, Alaska State's Capital would like to Sum() up all the Cities' CQI to show it as Alaska's CQI and show it live on the screen and Each crime reported anywhere in the City/County participating in CQI program should have an immediate effect on the State's CQI

Step 3 - Roll up cities' data for state

Now we have to calculate the whole state's CQI which is live updating on the big screen, we have State's view model called MainViewModel

internal class MainViewModel
{
    public MainViewModel(IObservable<CrimeReport> mainReport)
    {
         /// Here is the snippet also mentioned in Step 2
         //
           var cities = mainReport.GroupBy(k => k.City)
                  .Select(g => new CityDto(g.Key, g));

         ///// T h i s ///// Is //// Where //// I /// am /// Stuck
         //
          var allCqis = cities.Select(c => c.CityCqi); // gives you IObservable<IObservable<decimal>> ,

         /// Need to use latest of each observable in allCqi and sum them up
           //// How do I do it ?
     }
}

Constraints

  • Not all cities in Alaska currently participate in state's CQI program, but cities are enrolling day by day so I cannot have List and adding all the cities regardless of enrollment is not practical either. So it is IObservable which maintains only those cities not only participating but also have sent at least one CrimeReport object.

Full Source code

Source can be downloaded by clicking Here

Originally asked question

I have a single hot observable of multiple hot observables...

IObservable<IObservable<decimal>>

I would like an observable that when subscribed will keep its observer informed of the sum of all "Latest" decimal numbers from all observables inside.

How can I achieve that ? I tried CombineLatest(...) but could not get it right.

Thanks

解决方案

The Rxx library has an overload of CombineLatest() which takes an IObservable<IObservable<T>>. If you use this overload, then the solution is easy:

var runningSum = allCqis
    .Select(cqi => cqi.StartWith(0)) // start each inner sequence off with 0
    .CombineLatest() // produces an IObservable<IList<decimal>>
    .Select(cqis => cqis.Sum()); // LINQ operator Sum(IEnumerable<decimal>)

Looking at the source code for Rxx.CombineLatest might be useful to see how the problem is solved "under the hood"

这篇关于如何获得的总和&QUOT;最后&QUOT;小数将N热观测&LT的物品;实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆