首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在一个大的数据列表中计算多个布尔和十进制比较?

如何在一个大的数据列表中计算多个布尔和十进制比较?
EN

Software Engineering用户
提问于 2017-03-30 15:40:35
回答 2查看 100关注 0票数 2

我在设计上有问题,没人帮我解决。除了你。

系统处理数据文件。每一行都可以与用户选择的多个标准进行比较。对于该条件,行为true或false。

每个标准也有一个价格和一个成本(和一个保证金:价格-成本)。但是,只有当一行符合其中一项标准时,才会向用户收费。他们只支付其中一个匹配的标准:使用的应该是一个有最高的保证金。

从结构上看,在伪代码中如下所示:

代码语言:javascript
复制
SystemRow
{
    bool Criteria1 { get; set; }
    bool Criteria2 { get; set; } //etc
}

有一个单独的DTO,它将用户选择的标准作为位Enum保存。它与行一起传递到行处理函数中。

代码语言:javascript
复制
ProcessRow(selectedCriteria, row)
{
    if(selectedCriteria.HasFlag(CriteriaEnum.Criteria1)
    {
        // this sets row.Critera1 to true if it matches conditions
        EvaluateRowForCriteria1(row);
    }
    // then evaluate other criteria one by one
}

CalculatePrice(ListOfRows)
{
    decimal runningTotal;
    foreach(row in ListOfRows)
    {
       runningTotal += [the cost of one - and only one - matching criteria]
    }
}

根据SRP,这些函数中的每一个都存在于一个单独的类中。

我可以想出几种方法来做到这一点,但每一种方法都很混乱:维护起来很难,效率也很低。

首先,我可以在“行”中添加“价格”和“保证金”属性。然后,在"ProcessRow“所在的类中,我可以从DB中提取所有的价格和利润,并将它们存储在局部变量中。在"ProcessRow“期间,我可以比较一个标准的边际和行的标志,如果更好的话,可以指定价格。然后我可以用CalculatePrice来计算价格。

第二,我可以在CalculatePrice中获取价格和保证金。然后,对于每一行,我可以在行上使用选定的CriteriaX,找到要充电的正确的一个,并将其添加到正在运行的总数中。

造成这种混乱的原因是,大约有20个这样的标准。因此,无论哪种方式,如果我不想去Db获取每行的值,就必须有大量的变量。

这里有更好的设计吗?

EN

回答 2

Software Engineering用户

回答已采纳

发布于 2017-03-30 18:05:20

分析您的方法

现状:

  • 您不预先知道用户所需的标准;
  • 保留用于容器中查询的条件;
  • 你遍历所有的行;
  • 对于每一行,您都要查找所有匹配条件;
  • 你的问题是通过最大限度地提高每一行的价格;

你目前的选择是:

  • 选项A:在匹配过程中对行进行定价,如果另一个匹配标准有更好的余地,则更改价格;
  • 选项B:在求和时对行进行定价,跟踪最佳标准。

由于您有20多个标准,所以这两个解决方案都意味着检查所有匹配的标准。在最坏的情况下,你会试图匹配所有的20个条件:这是19个太多!

更好的替代

我建议你不要问自己哪一个是最有利可图的标准,每一行都是这样的:

  • 首先,通过降低盈利顺序,订购用户所要求的选择标准容器。
  • 然后,对于给定的行,依次按正确的顺序尝试每个条件。因此,当一个标准匹配时,它是最有利可图的,并且您不再需要匹配同一行的其余条件。
  • 您可以在处理行时或进行求和时计算价格:无论如何,您只有一个价格可供使用。

这种方法大大减少了成功行的匹配时间。对于未选定的行,性能不变。

票数 1
EN

Software Engineering用户

发布于 2017-03-30 18:53:40

将条件建模为类层次结构,而不仅仅是字符串列表:从公共接口或抽象基类派生每个条件类:

代码语言:javascript
复制
  interface ICriteria
  { 
      bool DoesItMatch(Row row);
      double Price{get;}
      double Cost{get;}
  }

现在,您所需要的只是一个工厂类,它从用户的选择中创建一个具体的ICriteria对象列表(我假设它只会查询您的db一次)。在您有了这个列表之后,按页边距降序排序。那么成本评估就会非常简单

代码语言:javascript
复制
double CalculateHighestMargin(List<ICriteria> orderedCriterias, row)
{
     foreach(var crit in orderedCriterias)
     {
        if(crit.DoesItMatch(row))
            return crit.Price - crit.Cost;
     }
     return 0;
}

注不需要存储每一行对象中的行的布尔值,也不需要存储每一行的价格和成本(至少不需要存储问题中描述的需求)。

票数 1
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/345249

复制
相关文章

相似问题

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